Merge pull request #548 from volatilityfoundation/feature/deprecate-symbol-shift

Core: Bump API to 2.0.0 and remove symbol_shift
This commit is contained in:
ikelos
2021-10-06 21:04:14 +01:00
committed by GitHub
99 changed files with 164 additions and 240 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ class CommandLine:
"""Executes the command line module, taking the system arguments,
determining the plugin to run and then running it."""
volatility3.framework.require_interface_version(1, 0, 0)
volatility3.framework.require_interface_version(2, 0, 0)
renderers = dict([(x.name.lower(), x) for x in framework.class_subclasses(text_renderer.CLIRenderer)])
+1 -1
View File
@@ -43,7 +43,7 @@ class VolShell(cli.CommandLine):
determining the plugin to run and then running it."""
sys.stdout.write(f"Volshell (Volatility 3 Framework) {constants.PACKAGE_VERSION}\n")
framework.require_interface_version(1, 0, 0)
framework.require_interface_version(2, 0, 0)
parser = argparse.ArgumentParser(prog = self.CLI_NAME,
description = "A tool for interactivate forensic analysis of memory images")
+1 -1
View File
@@ -26,7 +26,7 @@ except ImportError:
class Volshell(interfaces.plugins.PluginInterface):
"""Shell environment to directly interact with a memory image."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -38,11 +38,6 @@ class KernelModule(interfaces.automagic.AutomagicInterface):
offset_config_path = interfaces.configuration.path_join(new_config_path, 'offset')
offset = context.config[layer_kvo_config_path]
context.config[offset_config_path] = offset
elif isinstance(requirement.requirements[req], configuration.requirements.SymbolTableRequirement):
symbol_shift_config_path = interfaces.configuration.path_join(new_config_path,
req,
'symbol_shift')
context.config[symbol_shift_config_path] = 0
# Now construct the module based on the sub-requirements
requirement.construct(context, config_path)
@@ -5,7 +5,7 @@
import logging
from typing import Any, Iterable, List, Tuple, Type, Optional, Callable
from volatility3.framework import interfaces, constants, layers, exceptions
from volatility3.framework import interfaces, constants
from volatility3.framework.automagic import symbol_cache
from volatility3.framework.configuration import requirements
from volatility3.framework.layers import scanners
@@ -112,27 +112,8 @@ class SymbolFinder(interfaces.automagic.AutomagicInterface):
context.config[path_join(config_path, requirement.name, "isf_url")] = isf_path
context.config[path_join(config_path, requirement.name, "symbol_mask")] = layer.address_mask
# Set a default symbol_shift when attempt to determine it,
# so we can create the symbols which are used in finding the aslr_shift anyway
if not context.config.get(path_join(config_path, requirement.name, "symbol_shift"), None):
# Don't overwrite it if it's already been set, it will be manually refound if not present
prefound_kaslr_value = context.layers[layer_name].metadata.get('kaslr_value', 0)
context.config[path_join(config_path, requirement.name, "symbol_shift")] = prefound_kaslr_value
# Construct the appropriate symbol table
requirement.construct(context, config_path)
# Apply the ASLR masking (only if we're not already shifted)
if self.find_aslr and not context.config.get(path_join(config_path, requirement.name, "symbol_shift"),
None):
unmasked_symbol_table_name = context.config.get(path_join(config_path, requirement.name), None)
if not unmasked_symbol_table_name:
raise exceptions.SymbolSpaceError("Symbol table could not be constructed")
if not isinstance(layer, layers.intel.Intel):
raise TypeError("Layer name {} is not an intel space")
aslr_shift = self.find_aslr(context, unmasked_symbol_table_name, layer.config['memory_layer'])
context.config[path_join(config_path, requirement.name, "symbol_shift")] = aslr_shift
context.symbol_space.clear_symbol_cache(unmasked_symbol_table_name)
break
else:
if symbol_files:
+3 -4
View File
@@ -38,9 +38,9 @@ BANG = "!"
"""Constant used to delimit table names from type names when referring to a symbol"""
# We use the SemVer 2.0.0 versioning scheme
VERSION_MAJOR = 1 # Number of releases of the library with a breaking change
VERSION_MINOR = 2 # Number of changes that only add to the interface
VERSION_PATCH = 1 # Number of changes that do not change the interface
VERSION_MAJOR = 2 # Number of releases of the library with a breaking change
VERSION_MINOR = 0 # Number of changes that only add to the interface
VERSION_PATCH = 0 # Number of changes that do not change the interface
VERSION_SUFFIX = ""
# TODO: At version 2.0.0, remove the symbol_shift feature
@@ -94,7 +94,6 @@ ISF_MINIMUM_SUPPORTED = (2, 0, 0)
"""The minimum supported version of the Intermediate Symbol Format"""
ISF_MINIMUM_DEPRECATED = (3, 9, 9)
"""The highest version of the ISF that's deprecated (usually higher than supported)"""
OFFLINE = False
"""Whether to go online to retrieve missing/necessary JSON files"""
+1 -1
View File
@@ -54,7 +54,7 @@ class ScannerInterface(interfaces.configuration.VersionableInterface, metaclass
"""
thread_safe = False
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self) -> None:
super().__init__()
+1 -7
View File
@@ -8,7 +8,6 @@ from abc import abstractmethod, ABC
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, Mapping
from volatility3.framework import constants, exceptions, interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import configuration, objects
from volatility3.framework.interfaces.configuration import RequirementInterface
@@ -302,12 +301,7 @@ class SymbolTableInterface(BaseSymbolTableInterface, configuration.ConfigurableI
@classmethod
def get_requirements(cls) -> List[RequirementInterface]:
return super().get_requirements() + [
requirements.IntRequirement(
name = 'symbol_shift', description = 'Symbol Shift', optional = True, default = 0),
requirements.IntRequirement(
name = 'symbol_mask', description = 'Address mask for symbols', optional = True, default = 0),
]
return super().get_requirements()
class NativeTableInterface(BaseSymbolTableInterface):
@@ -11,7 +11,7 @@ from volatility3.framework.layers.scanners import multiregexp
class BytesScanner(layers.ScannerInterface):
thread_safe = True
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, needle: bytes) -> None:
super().__init__()
@@ -32,7 +32,7 @@ class BytesScanner(layers.ScannerInterface):
class RegExScanner(layers.ScannerInterface):
thread_safe = True
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, pattern: bytes, flags: int = 0) -> None:
super().__init__()
@@ -51,7 +51,7 @@ class RegExScanner(layers.ScannerInterface):
class MultiStringScanner(layers.ScannerInterface):
thread_safe = True
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, patterns: List[bytes]) -> None:
super().__init__()
+1 -1
View File
@@ -15,7 +15,7 @@ vollog = logging.getLogger(__name__)
class Banners(interfaces.plugins.PluginInterface):
"""Attempts to identify potential linux banners in an image"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -17,7 +17,7 @@ class ConfigWriter(plugins.PluginInterface):
"""Runs the automagics and both prints and outputs configuration in the
output directory."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -8,7 +8,7 @@ from volatility3.framework.interfaces import plugins
class FrameworkInfo(plugins.PluginInterface):
"""Plugin to list the various modular components of Volatility"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -22,7 +22,7 @@ vollog = logging.getLogger(__name__)
class IsfInfo(plugins.PluginInterface):
"""Determines information about the currently available ISF files, or a specific one"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
+1 -1
View File
@@ -17,7 +17,7 @@ class LayerWriter(plugins.PluginInterface):
default_block_size = 0x500000
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
@classmethod
+1 -1
View File
@@ -21,7 +21,7 @@ from volatility3.plugins.linux import pslist
class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Recovers bash command history from memory."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -18,7 +18,7 @@ vollog = logging.getLogger(__name__)
class Check_afinfo(plugins.PluginInterface):
"""Verifies the operation function pointers of network protocols."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -14,7 +14,7 @@ vollog = logging.getLogger(__name__)
class Check_creds(interfaces.plugins.PluginInterface):
"""Checks if any processes are sharing credential structures"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -17,7 +17,7 @@ vollog = logging.getLogger(__name__)
class Check_idt(interfaces.plugins.PluginInterface):
""" Checks if the IDT has been altered """
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -18,7 +18,7 @@ vollog = logging.getLogger(__name__)
class Check_modules(plugins.PluginInterface):
"""Compares module list to sysfs info, if available"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -25,7 +25,7 @@ except ImportError:
class Check_syscall(plugins.PluginInterface):
"""Check system call table for hooks."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -17,7 +17,7 @@ from volatility3.plugins.linux import pslist
class Elfs(plugins.PluginInterface):
"""Lists all memory mapped ELF files for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -16,7 +16,7 @@ vollog = logging.getLogger(__name__)
class Keyboard_notifiers(interfaces.plugins.PluginInterface):
"""Parses the keyboard notifier call chain"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -363,7 +363,7 @@ class KmsgFiveTen(ABCKmsg):
class Kmsg(plugins.PluginInterface):
"""Kernel log buffer reader"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
+1 -1
View File
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class Lsmod(plugins.PluginInterface):
"""Lists loaded kernel modules."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
@classmethod
+1 -1
View File
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class Lsof(plugins.PluginInterface):
"""Lists all memory maps for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -15,7 +15,7 @@ from volatility3.plugins.linux import pslist
class Malfind(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -15,7 +15,7 @@ from volatility3.plugins.linux import pslist
class Maps(plugins.PluginInterface):
"""Lists all memory maps for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -11,7 +11,7 @@ from volatility3.framework.objects import utility
class PsList(interfaces.plugins.PluginInterface):
"""Lists the processes present in a particular linux memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class tty_check(plugins.PluginInterface):
"""Checks tty devices for hooks"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -20,7 +20,7 @@ from volatility3.plugins.mac import pslist
class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Recovers bash command history from memory."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -18,7 +18,7 @@ vollog = logging.getLogger(__name__)
class Check_syscall(plugins.PluginInterface):
"""Check system call table for hooks."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -20,7 +20,7 @@ vollog = logging.getLogger(__name__)
class Check_sysctl(plugins.PluginInterface):
"""Check sysctl handlers for hooks."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class Check_trap_table(plugins.PluginInterface):
"""Check mach trap table for hooks."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -11,7 +11,7 @@ from volatility3.framework.symbols import mac
class Ifconfig(plugins.PluginInterface):
"""Lists loaded kernel modules"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -13,7 +13,7 @@ from volatility3.plugins.mac import lsmod, kauth_scopes
class Kauth_listeners(interfaces.plugins.PluginInterface):
""" Lists kauth listeners and their status """
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -18,7 +18,7 @@ class Kauth_scopes(interfaces.plugins.PluginInterface):
""" Lists kauth scopes and their status """
_version = (2, 0, 0)
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -14,7 +14,7 @@ from volatility3.plugins.mac import pslist
class Kevents(interfaces.plugins.PluginInterface):
""" Lists event handlers registered by processes """
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
event_types = {
@@ -18,7 +18,7 @@ vollog = logging.getLogger(__name__)
class List_Files(plugins.PluginInterface):
"""Lists all open file descriptors for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -15,7 +15,7 @@ from volatility3.framework.renderers import format_hints
class Lsmod(plugins.PluginInterface):
"""Lists loaded kernel modules."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
+1 -1
View File
@@ -16,7 +16,7 @@ vollog = logging.getLogger(__name__)
class Lsof(plugins.PluginInterface):
"""Lists all open file descriptors for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -13,7 +13,7 @@ from volatility3.plugins.mac import pslist
class Malfind(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -14,7 +14,7 @@ class Mount(plugins.PluginInterface):
"""A module containing a collection of plugins that produce data typically
foundin Mac's mount command"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
+1 -1
View File
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class Netstat(plugins.PluginInterface):
"""Lists all network connections for all processes."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -12,7 +12,7 @@ from volatility3.plugins.mac import pslist
class Maps(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
+1 -1
View File
@@ -14,7 +14,7 @@ from volatility3.plugins.mac import pslist
class Psaux(plugins.PluginInterface):
"""Recovers program command line arguments."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -16,7 +16,7 @@ vollog = logging.getLogger(__name__)
class PsList(interfaces.plugins.PluginInterface):
"""Lists the processes present in a particular mac memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (3, 0, 0)
pslist_methods = ['tasks', 'allproc', 'process_group', 'sessions', 'pid_hash_table']
+1 -1
View File
@@ -13,7 +13,7 @@ class PsTree(plugins.PluginInterface):
"""Plugin for listing processes in a tree based on their parent process
ID."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)
class Socket_filters(plugins.PluginInterface):
"""Enumerates kernel socket filters."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -18,7 +18,7 @@ vollog = logging.getLogger(__name__)
class Timers(plugins.PluginInterface):
"""Check for malicious kernel timers."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -20,7 +20,7 @@ vollog = logging.getLogger(__name__)
class Trustedbsd(plugins.PluginInterface):
"""Checks for malicious trustedbsd modules"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -10,7 +10,7 @@ from volatility3.framework.objects import utility
class VFSevents(interfaces.plugins.PluginInterface):
""" Lists processes that are filtering file system events """
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
event_types = [
"CREATE_FILE", "DELETE", "STAT_CHANGED", "RENAME", "CONTENT_MODIFIED", "EXCHANGE", "FINDER_INFO_CHANGED",
+1 -1
View File
@@ -42,7 +42,7 @@ class Timeliner(interfaces.plugins.PluginInterface):
"""Runs all relevant plugins that provide time related information and
orders the results by time."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -20,7 +20,7 @@ vollog = logging.getLogger(__name__)
class BigPools(interfaces.plugins.PluginInterface):
"""List big page pools."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
@@ -28,7 +28,7 @@ class BigPools(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.StringRequirement(name = 'tags',
description = "Comma separated list of pool tags to filter pools returned",
optional = True,
@@ -105,7 +105,6 @@ class BigPools(interfaces.plugins.PluginInterface):
tags = [tag for tag in self.config["tags"].split(',')]
else:
tags = None
kernel = self.context.modules[self.config['kernel']]
for big_pool in self.list_big_pools(context = self.context,
@@ -21,14 +21,14 @@ vollog = logging.getLogger(__name__)
class Cachedump(interfaces.plugins.PluginInterface):
"""Dumps lsa secrets from memory"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'lsadump', plugin = lsadump.Lsadump, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'hashdump', plugin = hashdump.Hashdump, version = (1, 1, 0))
@@ -44,7 +44,7 @@ class Cachedump(interfaces.plugins.PluginInterface):
hmac_md5 = HMAC.new(nlkm, ch)
rc4key = hmac_md5.digest()
rc4 = ARC4.new(rc4key)
data = rc4.encrypt(edata) # lgtm [py/weak-cryptographic-algorithm]
data = rc4.encrypt(edata) # lgtm [py/weak-cryptographic-algorithm]
else:
# based on Based on code from http://lab.mediaservice.net/code/cachedump.rb
aes = AES.new(nlkm[16:32], AES.MODE_CBC, ch)
@@ -129,7 +129,6 @@ class Cachedump(interfaces.plugins.PluginInterface):
offset = self.config.get('offset', None)
syshive = sechive = None
kernel = self.context.modules[self.config['kernel']]
for hive in hivelist.HiveList.list_hives(self.context,
@@ -19,14 +19,14 @@ vollog = logging.getLogger(__name__)
class Callbacks(interfaces.plugins.PluginInterface):
"""Lists kernel callbacks and notification routines."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'ssdt', plugin = ssdt.SSDT, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'svcscan', plugin = svcscan.SvcScan, version = (1, 0, 0))
]
@@ -15,7 +15,7 @@ vollog = logging.getLogger(__name__)
class CmdLine(interfaces.plugins.PluginInterface):
"""Lists process command line arguments."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
@@ -23,7 +23,7 @@ class CmdLine(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
element_type = int,
@@ -54,7 +54,6 @@ class CmdLine(interfaces.plugins.PluginInterface):
return result_text
def _generator(self, procs):
kernel = self.context.modules[self.config['kernel']]
for proc in procs:
@@ -78,9 +77,7 @@ class CmdLine(interfaces.plugins.PluginInterface):
yield (0, (proc.UniqueProcessId, process_name, result_text))
def run(self):
kernel = self.context.modules[self.config['kernel']]
filter_func = pslist.PsList.create_pid_filter(self.config.get('pid', None))
return renderers.TreeGrid([("PID", int), ("Process", str), ("Args", str)],
@@ -20,7 +20,7 @@ vollog = logging.getLogger(__name__)
class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Lists the loaded modules in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
@classmethod
@@ -28,7 +28,7 @@ class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'info', component = info.Info, version = (1, 0, 0)),
requirements.ListRequirement(name = 'pid',
@@ -136,7 +136,6 @@ class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
if file_handle:
file_handle.close()
file_output = file_handle.preferred_filename
try:
dllbase = format_hints.Hex(entry.DllBase)
except exceptions.InvalidAddressException:
@@ -155,7 +154,6 @@ class DllList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
def generate_timeline(self):
kernel = self.context.modules[self.config['kernel']]
for row in self._generator(
pslist.PsList.list_processes(context = self.context,
layer_name = kernel.layer_name,
@@ -22,7 +22,7 @@ MAJOR_FUNCTIONS = [
class DriverIrp(interfaces.plugins.PluginInterface):
"""List IRPs for drivers in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
@@ -13,14 +13,14 @@ from volatility3.plugins.windows import poolscanner
class DriverScan(interfaces.plugins.PluginInterface):
"""Scans for drivers present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'poolscanner', plugin = poolscanner.PoolScanner, version = (1, 0, 0)),
]
@@ -5,7 +5,6 @@
import logging
import ntpath
from typing import List, Tuple, Type, Optional, Generator
from volatility3.framework import interfaces, renderers, exceptions, constants
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
@@ -26,7 +25,7 @@ EXTENSION_CACHE_MAP = {
class DumpFiles(interfaces.plugins.PluginInterface):
"""Dumps cached file contents from Windows memory samples."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
@@ -34,7 +33,7 @@ class DumpFiles(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.IntRequirement(name = 'pid',
description = "Process ID to include (all other processes are excluded)",
optional = True),
@@ -237,9 +236,9 @@ class DumpFiles(interfaces.plugins.PluginInterface):
file_obj = self.context.object(
kernel.symbol_table_name + constants.BANG + "_FILE_OBJECT",
layer_name = layer_name,
layer_name = layer_name,
native_layer_name = kernel.layer_name,
offset = offset)
offset = offset)
for result in self.process_file_object(self.context, kernel.layer_name, self.open, file_obj):
yield (0, result)
except exceptions.InvalidAddressException:
@@ -250,7 +249,6 @@ class DumpFiles(interfaces.plugins.PluginInterface):
offsets = []
# a list of processes matching the pid filter. all files for these process(es) will be dumped.
procs = []
kernel = self.context.modules[self.config['kernel']]
if self.config.get("virtaddr", None) is not None:
@@ -15,15 +15,15 @@ vollog = logging.getLogger(__name__)
class Envars(interfaces.plugins.PluginInterface):
"Display process environment variables"
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -13,13 +13,13 @@ from volatility3.plugins.windows import poolscanner
class FileScan(interfaces.plugins.PluginInterface):
"""Scans for file objects present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'poolscanner', plugin = poolscanner.PoolScanner, version = (1, 0, 0)),
]
@@ -30,8 +30,8 @@ def createservicesid(svc) -> str:
class GetServiceSIDs(interfaces.plugins.PluginInterface):
"""Lists process token sids."""
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -54,11 +54,12 @@ class GetServiceSIDs(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0))
]
def _generator(self):
kernel = self.context.modules[self.config['kernel']]
# Get the system hive
for hive in hivelist.HiveList.list_hives(context = self.context,
@@ -28,8 +28,8 @@ def find_sid_re(sid_string, sid_re_list) -> Union[str, interfaces.renderers.Base
class GetSIDs(interfaces.plugins.PluginInterface):
"""Print the SIDs owning each process"""
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -54,7 +54,7 @@ class GetSIDs(interfaces.plugins.PluginInterface):
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -24,7 +24,7 @@ except ImportError:
class Handles(interfaces.plugins.PluginInterface):
"""Lists process open handles."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
def __init__(self, *args, **kwargs):
@@ -39,7 +39,7 @@ class Handles(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.ListRequirement(name = 'pid',
element_type = int,
description = "Process IDs to include (all other processes are excluded)",
@@ -293,7 +293,6 @@ class Handles(interfaces.plugins.PluginInterface):
yield handle_table_entry
def _generator(self, procs):
kernel = self.context.modules[self.config['kernel']]
type_map = self.get_type_map(context = self.context,
@@ -21,14 +21,14 @@ vollog = logging.getLogger(__name__)
class Hashdump(interfaces.plugins.PluginInterface):
"""Dumps user hashes from memory"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 1, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0))
]
@@ -132,7 +132,7 @@ class Hashdump(interfaces.plugins.PluginInterface):
rc4_key = md5.digest()
rc4 = ARC4.new(rc4_key)
hbootkey = rc4.encrypt(sam_data[0x80:0xA0]) # lgtm [py/weak-cryptographic-algorithm]
hbootkey = rc4.encrypt(sam_data[0x80:0xA0]) # lgtm [py/weak-cryptographic-algorithm]
return hbootkey
elif revision == 3:
# AES encrypted
@@ -151,7 +151,7 @@ class Hashdump(interfaces.plugins.PluginInterface):
des2 = DES.new(des_k2, DES.MODE_ECB)
cipher = AES.new(hbootkey[:16], AES.MODE_CBC, salt)
obfkey = cipher.decrypt(enc_hash)
return des1.decrypt(obfkey[:8]) + des2.decrypt(obfkey[8:16]) # lgtm [py/weak-cryptographic-algorithm]
return des1.decrypt(obfkey[:8]) + des2.decrypt(obfkey[8:16]) # lgtm [py/weak-cryptographic-algorithm]
@classmethod
def get_user_hashes(cls, user: registry.CM_KEY_NODE, samhive: registry.RegistryHive,
@@ -229,9 +229,9 @@ class Hashdump(interfaces.plugins.PluginInterface):
md5.update(hbootkey[:0x10] + pack("<L", rid) + lmntstr)
rc4_key = md5.digest()
rc4 = ARC4.new(rc4_key)
obfkey = rc4.encrypt(enc_hash) # lgtm [py/weak-cryptographic-algorithm]
obfkey = rc4.encrypt(enc_hash) # lgtm [py/weak-cryptographic-algorithm]
return des1.decrypt(obfkey[:8]) + des2.decrypt(obfkey[8:]) # lgtm [py/weak-cryptographic-algorithm]
return des1.decrypt(obfkey[:8]) + des2.decrypt(obfkey[8:]) # lgtm [py/weak-cryptographic-algorithm]
@classmethod
def get_user_name(cls, user: registry.CM_KEY_NODE, samhive: registry.RegistryHive) -> Optional[bytes]:
@@ -288,7 +288,6 @@ class Hashdump(interfaces.plugins.PluginInterface):
syshive = None
samhive = None
kernel = self.context.modules[self.config['kernel']]
for hive in hivelist.HiveList.list_hives(self.context,
self.config_path,
kernel.layer_name,
@@ -16,14 +16,14 @@ from volatility3.framework.symbols.windows import extensions
class Info(plugins.PluginInterface):
"""Show OS & kernel details of the memory sample being analyzed."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
]
@classmethod
@@ -21,14 +21,14 @@ vollog = logging.getLogger(__name__)
class Lsadump(interfaces.plugins.PluginInterface):
"""Dumps lsa secrets from memory"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'hashdump', component = hashdump.Hashdump, version = (1, 1, 0)),
requirements.VersionRequirement(name = 'hivelist', component = hivelist.HiveList, version = (1, 0, 0))
]
@@ -84,7 +84,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
rc4key = md5.digest()
rc4 = ARC4.new(rc4key)
lsa_key = rc4.decrypt(obf_lsa_key[12:60]) # lgtm [py/weak-cryptographic-algorithm]
lsa_key = rc4.decrypt(obf_lsa_key[12:60]) # lgtm [py/weak-cryptographic-algorithm]
lsa_key = lsa_key[0x10:0x20]
else:
lsa_key = cls.decrypt_aes(obf_lsa_key, bootkey)
@@ -125,7 +125,7 @@ class Lsadump(interfaces.plugins.PluginInterface):
des_key = hashdump.Hashdump.sidbytes_to_key(block_key)
des = DES.new(des_key, DES.MODE_ECB)
enc_block = enc_block + b"\x00" * int(abs(8 - len(enc_block)) % 8)
decrypted_data += des.decrypt(enc_block) # lgtm [py/weak-cryptographic-algorithm]
decrypted_data += des.decrypt(enc_block) # lgtm [py/weak-cryptographic-algorithm]
j += 7
if len(key[j:j + 7]) < 7:
j = len(key[j:j + 7])
@@ -17,14 +17,14 @@ vollog = logging.getLogger(__name__)
class Malfind(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.ListRequirement(name = 'pid',
element_type = int,
description = "Process IDs to include (all other processes are excluded)",
@@ -103,8 +103,8 @@ class Malfind(interfaces.plugins.PluginInterface):
continue
if (vad.get_private_memory() == 1
and vad.get_tag() == "VadS") or (vad.get_private_memory() == 0
and protection_string != "PAGE_EXECUTE_WRITECOPY"):
and vad.get_tag() == "VadS") or (vad.get_private_memory() == 0
and protection_string != "PAGE_EXECUTE_WRITECOPY"):
if cls.is_vad_empty(proc_layer, vad):
continue
@@ -16,14 +16,14 @@ vollog = logging.getLogger(__name__)
class Memmap(interfaces.plugins.PluginInterface):
"""Prints the memory map"""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.IntRequirement(name = 'pid',
description = "Process ID to include (all other processes are excluded)",
@@ -34,6 +34,7 @@ class Memmap(interfaces.plugins.PluginInterface):
optional = True)
]
def _generator(self, procs):
for proc in procs:
pid = "Unknown"
@@ -17,14 +17,14 @@ vollog = logging.getLogger(__name__)
class ModScan(interfaces.plugins.PluginInterface):
"""Scans for modules present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'poolerscanner',
component = poolscanner.PoolScanner,
version = (1, 0, 0)),
@@ -19,14 +19,14 @@ vollog = logging.getLogger(__name__)
class Modules(interfaces.plugins.PluginInterface):
"""Lists the loaded kernel modules."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 1, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'pslist', component = pslist.PsList, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'dlllist', component = dlllist.DllList, version = (2, 0, 0)),
requirements.BooleanRequirement(name = 'dump',
@@ -13,13 +13,13 @@ from volatility3.plugins.windows import poolscanner
class MutantScan(interfaces.plugins.PluginInterface):
"""Scans for mutexes present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'poolscanner', plugin = poolscanner.PoolScanner, version = (1, 0, 0)),
]
@@ -22,14 +22,14 @@ vollog = logging.getLogger(__name__)
class NetScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Scans for network objects present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'poolscanner',
component = poolscanner.PoolScanner,
version = (1, 0, 0)),
@@ -20,14 +20,14 @@ vollog = logging.getLogger(__name__)
class NetStat(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Traverses network tracking structures present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'netscan', component = netscan.NetScan, version = (1, 0, 0)),
requirements.VersionRequirement(name = 'modules', component = modules.Modules, version = (1, 0, 0)),
requirements.VersionRequirement(name = 'pdbutil', component = pdbutil.PDBUtility, version = (1, 0, 0)),
@@ -17,7 +17,7 @@ class Privs(interfaces.plugins.PluginInterface):
"""Lists process token privileges"""
_version = (1, 2, 0)
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -41,7 +41,7 @@ class Privs(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -20,7 +20,7 @@ vollog = logging.getLogger(__name__)
class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Lists the processes present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
PHYSICAL_DEFAULT = False
@@ -22,14 +22,14 @@ vollog = logging.getLogger(__name__)
class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Scans for processes present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 1, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'info', component = info.Info, version = (1, 0, 0)),
requirements.ListRequirement(name = 'pid',
@@ -143,7 +143,6 @@ class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
def _generator(self):
kernel = self.context.modules[self.config['kernel']]
pe_table_name = intermed.IntermediateSymbolTable.create(self.context,
self.config_path,
"windows",
@@ -16,7 +16,7 @@ class PsTree(interfaces.plugins.PluginInterface):
"""Plugin for listing processes in a tree based on their parent process
ID."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
@@ -28,7 +28,7 @@ class PsTree(interfaces.plugins.PluginInterface):
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.BooleanRequirement(name = 'physical',
description = 'Display physical offsets instead of virtual',
default = pslist.PsList.PHYSICAL_DEFAULT,
@@ -17,7 +17,7 @@ class HiveGenerator:
"""Walks the registry HiveList linked list in a given direction and stores an invalid offset
if it's unable to fully walk the list"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, cmhive, forward = True):
self._cmhive = cmhive
@@ -39,14 +39,14 @@ class HiveGenerator:
class HiveList(interfaces.plugins.PluginInterface):
"""Lists the registry hives present in a particular memory image."""
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.StringRequirement(name = 'filter',
description = "String to filter hive names returned",
optional = True,
@@ -63,7 +63,6 @@ class HiveList(interfaces.plugins.PluginInterface):
def _generator(self) -> Iterator[Tuple[int, Tuple[int, str]]]:
chunk_size = 0x500000
kernel = self.context.modules[self.config['kernel']]
for hive_object in self.list_hive_objects(context = self.context,
@@ -15,14 +15,14 @@ class HiveScan(interfaces.plugins.PluginInterface):
"""Scans for registry hives present in a particular windows memory
image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'poolscanner', plugin = poolscanner.PoolScanner, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'bigpools', plugin = bigpools.BigPools, version = (1, 0, 0)),
]
@@ -66,12 +66,11 @@ class HiveScan(interfaces.plugins.PluginInterface):
yield mem_object
def _generator(self):
kernel = self.context.modules[self.config['kernel']]
for hive in self.scan_hives(self.context, kernel.layer_name, kernel.symbol_table_name):
yield (0, (format_hints.Hex(hive.vol.offset),))
yield (0, (format_hints.Hex(hive.vol.offset), ))
def run(self):
return renderers.TreeGrid([("Offset", format_hints.Hex)], self._generator())
@@ -19,14 +19,14 @@ vollog = logging.getLogger(__name__)
class PrintKey(interfaces.plugins.PluginInterface):
"""Lists the registry keys under a hive or specific key value."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0)),
requirements.IntRequirement(name = 'offset', description = "Hive Offset", default = None, optional = True),
requirements.StringRequirement(name = 'key',
@@ -41,10 +41,10 @@ class PrintKey(interfaces.plugins.PluginInterface):
@classmethod
def key_iterator(
cls,
hive: RegistryHive,
node_path: Sequence[objects.StructType] = None,
recurse: bool = False
cls,
hive: RegistryHive,
node_path: Sequence[objects.StructType] = None,
recurse: bool = False
) -> Iterable[Tuple[int, bool, datetime.datetime, str, bool, interfaces.objects.ObjectInterface]]:
"""Walks through a set of nodes from a given node (last one in
node_path). Avoids loops by not traversing into nodes already present
@@ -23,7 +23,7 @@ vollog = logging.getLogger(__name__)
class UserAssist(interfaces.plugins.PluginInterface):
"""Print userassist registry keys and information."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -38,7 +38,7 @@ class UserAssist(interfaces.plugins.PluginInterface):
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.IntRequirement(name = 'offset', description = "Hive Offset", default = None, optional = True),
requirements.PluginRequirement(name = 'hivelist', plugin = hivelist.HiveList, version = (1, 0, 0))
]
@@ -217,7 +217,6 @@ class UserAssist(interfaces.plugins.PluginInterface):
hive_offsets = None
if self.config.get('offset', None) is not None:
hive_offsets = [self.config.get('offset', None)]
kernel = self.context.modules[self.config['kernel']]
# get all the user hive offsets or use the one specified
@@ -18,14 +18,14 @@ from volatility3.plugins.windows import modules
class SSDT(plugins.PluginInterface):
"""Lists the system call table."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'modules', plugin = modules.Modules, version = (1, 0, 0)),
]
@@ -19,7 +19,7 @@ class Strings(interfaces.plugins.PluginInterface):
"""Reads output from the strings command and indicates which process(es) each string belongs to."""
_version = (1, 2, 0)
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
strings_pattern = re.compile(rb"^(?:\W*)([0-9]+)(?:\W*)(\w[\w\W]+)\n?")
@classmethod
@@ -42,7 +42,7 @@ class Strings(interfaces.plugins.PluginInterface):
def _generator(self) -> Generator[Tuple, None, None]:
"""Generates results from a strings file."""
string_list: List[Tuple[int, bytes]] = []
string_list: List[Tuple[int,bytes]] = []
# Test strings file format is accurate
accessor = resources.ResourceAccessor()
@@ -57,7 +57,6 @@ class Strings(interfaces.plugins.PluginInterface):
except ValueError:
vollog.error(f"Line in unrecognized format: line {count}")
line = strings_fp.readline()
kernel = self.context.modules[self.config['kernel']]
revmap = self.generate_mapping(self.context,
@@ -67,7 +66,7 @@ class Strings(interfaces.plugins.PluginInterface):
pid_list = self.config['pid'])
last_prog: float = 0
line_count: float = 0
line_count: float = 0
num_strings = len(string_list)
for offset, string in string_list:
line_count += 1
@@ -21,7 +21,7 @@ vollog = logging.getLogger(__name__)
class SvcScan(interfaces.plugins.PluginInterface):
"""Scans for windows services."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
@@ -29,7 +29,7 @@ class SvcScan(interfaces.plugins.PluginInterface):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.PluginRequirement(name = 'poolscanner', plugin = poolscanner.PoolScanner, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'vadyarascan', plugin = vadyarascan.VadYaraScan, version = (1, 0, 0))
@@ -15,13 +15,13 @@ from volatility3.plugins.windows import poolscanner
class SymlinkScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Scans for links present in a particular windows memory image."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls):
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
]
@classmethod
@@ -33,7 +33,7 @@ winnt_protections = {
class VadInfo(interfaces.plugins.PluginInterface):
"""Lists process memory ranges."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (2, 0, 0)
MAXSIZE_DEFAULT = 0
@@ -45,7 +45,7 @@ class VadInfo(interfaces.plugins.PluginInterface):
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
# Since we're calling the plugin, make sure we have the plugin's requirements
return [requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
# TODO: Convert this to a ListRequirement so that people can filter on sets of ranges
requirements.IntRequirement(name = 'address',
description = "Process virtual memory address to include " \
@@ -166,7 +166,6 @@ class VadInfo(interfaces.plugins.PluginInterface):
return file_handle
def _generator(self, procs):
kernel = self.context.modules[self.config['kernel']]
def passthrough(_: interfaces.objects.ObjectInterface) -> bool:
@@ -201,7 +200,6 @@ class VadInfo(interfaces.plugins.PluginInterface):
format_hints.Hex(vad.get_parent()), vad.get_file_name(), file_output))
def run(self):
kernel = self.context.modules[self.config['kernel']]
filter_func = pslist.PsList.create_pid_filter(self.config.get('pid', None))
@@ -17,14 +17,14 @@ vollog = logging.getLogger(__name__)
class VadYaraScan(interfaces.plugins.PluginInterface):
"""Scans all the Virtual Address Descriptor memory maps using yara."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.ModuleRequirement(name = 'kernel', description = 'Windows kernel',
architectures = ["Intel32", "Intel64"]),
architectures = ["Intel32", "Intel64"]),
requirements.BooleanRequirement(name = "wide",
description = "Match wide (unicode) strings",
default = False,
@@ -52,7 +52,6 @@ class VadYaraScan(interfaces.plugins.PluginInterface):
]
def _generator(self):
kernel = self.context.modules[self.config['kernel']]
rules = yarascan.YaraScan.process_yara_options(dict(self.config))
@@ -27,8 +27,8 @@ except ImportError:
class VerInfo(interfaces.plugins.PluginInterface):
"""Lists version information from PE files."""
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -16,7 +16,7 @@ vollog = logging.getLogger(__name__)
class VirtMap(interfaces.plugins.PluginInterface):
"""Lists virtual mapped sections."""
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -39,7 +39,7 @@ class YaraScanner(interfaces.layers.ScannerInterface):
class YaraScan(plugins.PluginInterface):
"""Scans kernel memory using yara rules (string or file)."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
_version = (1, 0, 0)
@classmethod
+8 -36
View File
@@ -13,14 +13,15 @@ import zipfile
from abc import ABCMeta
from typing import Any, Dict, Generator, Iterable, List, Optional, Type, Tuple, Mapping
from volatility3.framework.layers import resources
from volatility3 import schemas, symbols
from volatility3.framework import class_subclasses, constants, exceptions, interfaces, objects
from volatility3.framework.configuration import requirements
from volatility3.framework.layers import resources
from volatility3.framework.symbols import native, metadata
vollog = logging.getLogger(__name__)
# ## TODO
#
# All symbol tables should take a label to an object template
@@ -47,7 +48,6 @@ vollog = logging.getLogger(__name__)
def _construct_delegate_function(name: str, is_property: bool = False) -> Any:
def _delegate_function(self, *args, **kwargs):
if is_property:
return getattr(self._delegate, name)
@@ -82,9 +82,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
native_types: interfaces.symbols.NativeTableInterface = None,
table_mapping: Optional[Dict[str, str]] = None,
validate: bool = True,
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None,
symbol_shift: int = 0,
symbol_mask: int = 0) -> None:
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None) -> None:
"""Instantiates a SymbolTable based on an IntermediateSymbolFormat JSON file. This is validated against the
appropriate schema. The validation can be disabled by passing validate = False, but this should almost never be
done.
@@ -98,8 +96,6 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
table_mapping: A dictionary linking names referenced in the file with symbol tables in the context
validate: Determines whether the ISF file will be validated against the appropriate schema
class_types: A dictionary of type names and classes that override StructType when they are instantiated
symbol_shift: An offset by which to alter all returned symbols for this table
symbol_mask: An address mask used for all returned symbol offsets from this table (a mask of 0 disables masking)
"""
# Check there are no obvious errors
# Open the file and test the version
@@ -136,13 +132,6 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
# Since we've been created with parameters, ensure our config is populated likewise
self.config['isf_url'] = isf_url
if symbol_shift:
vollog.warning(
"Symbol_shift support has been deprecated and will be removed in the next major release of Volatility 3"
)
self.config['symbol_shift'] = symbol_shift
self.config['symbol_mask'] = symbol_mask
@staticmethod
def _closest_version(version: str, versions: Dict[Tuple[int, int, int], Type['ISFormatTable']]) \
-> Type['ISFormatTable']:
@@ -225,9 +214,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
filename: str,
native_types: Optional[interfaces.symbols.NativeTableInterface] = None,
table_mapping: Optional[Dict[str, str]] = None,
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None,
symbol_shift: int = 0,
symbol_mask: int = 0) -> str:
class_types: Optional[Mapping[str, Type[interfaces.objects.ObjectInterface]]] = None) -> str:
"""Takes a context and loads an intermediate symbol table based on a
filename.
@@ -238,8 +225,6 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
filename: Basename of the file to find under the sub_path
native_types: Set of native types, defaults to native types read from the intermediate symbol format file
table_mapping: a dictionary of table names mentioned within the ISF file, and the tables within the context which they map to
symbol_shift: An offset by which to alter all returned symbols for this table
symbol_mask: An address mask used for all returned symbol offsets from this table (a mask of 0 disables masking)
Returns:
the name of the added symbol table
@@ -254,9 +239,7 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
isf_url = urls[0],
native_types = native_types,
table_mapping = table_mapping,
class_types = class_types,
symbol_shift = symbol_shift,
symbol_mask = symbol_mask)
class_types = class_types)
context.symbol_space.append(table)
return table_name
@@ -341,10 +324,7 @@ class Version1Format(ISFormatTable):
symbol = self._json_object['symbols'].get(name, None)
if not symbol:
raise exceptions.SymbolError(name, self.name, f"Unknown symbol: {name}")
address = symbol['address'] + self.config.get('symbol_shift', 0)
if self.config.get('symbol_mask', 0):
address = address & self.config['symbol_mask']
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = address)
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = symbol['address'])
return self._symbol_cache[name]
@property
@@ -546,12 +526,8 @@ class Version3Format(Version2Format):
if 'type' in symbol:
symbol_type = self._interdict_to_template(symbol['type'])
# Mask the addresses if necessary
address = symbol['address'] + self.config.get('symbol_shift', 0)
if self.config.get('symbol_mask', 0):
address = address & self.config['symbol_mask']
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name,
address = address,
address = symbol['address'],
type = symbol_type)
return self._symbol_cache[name]
@@ -606,12 +582,8 @@ class Version5Format(Version4Format):
if 'constant_data' in symbol:
symbol_constant_data = base64.b64decode(symbol.get('constant_data'))
# Mask the addresses if necessary
address = symbol['address'] + self.config.get('symbol_shift', 0)
if self.config.get('symbol_mask', 0):
address = address & self.config['symbol_mask']
self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name,
address = address,
address = symbol['address'],
type = symbol_type,
constant_data = symbol_constant_data)
return self._symbol_cache[name]
@@ -41,7 +41,7 @@ class LinuxUtilities(interfaces.configuration.VersionableInterface):
"""Class with multiple useful linux functions."""
_version = (2, 0, 0)
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
framework.require_interface_version(*_required_framework_version)
@@ -38,7 +38,7 @@ class MacUtilities(interfaces.configuration.VersionableInterface):
1.3.0 -> add parameter to lookup_module_address to pass kernel module name
"""
_version = (1, 3, 0)
_required_framework_version = (1, 2, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def mask_mods_list(cls, context: interfaces.context.ContextInterface, layer_name: str,
@@ -25,7 +25,7 @@ class PDBUtility(interfaces.configuration.VersionableInterface):
"""Class to handle and manage all getting symbols based on MZ header"""
_version = (1, 0, 0)
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def symbol_table_from_offset(
+1 -1
View File
@@ -114,8 +114,8 @@ class PoolHeaderScanner(interfaces.layers.ScannerInterface):
class PoolScanner(plugins.PluginInterface):
"""A generic pool scanner plugin."""
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -10,7 +10,7 @@ from volatility3.plugins.windows.registry import hivelist, printkey
class Certificates(interfaces.plugins.PluginInterface):
"""Lists the certificates in the registry's Certificate Store."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
+1 -1
View File
@@ -13,7 +13,7 @@ vollog = logging.getLogger(__name__)
class Statistics(plugins.PluginInterface):
_required_framework_version = (1, 0, 0)
_required_framework_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: