Linux: Update all plugins to ModuleRequirement

This commit is contained in:
Mike Auty
2021-07-22 22:40:09 +01:00
parent abbd516f99
commit 1480aca453
15 changed files with 116 additions and 161 deletions
+4 -9
View File
@@ -21,16 +21,13 @@ from volatility3.plugins.linux import pslist
class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Recovers bash command history from memory."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
element_type = int,
description = "Process IDs to include (all other processes are excluded)",
@@ -38,7 +35,7 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
]
def _generator(self, tasks):
is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux"])
is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux.symbol_table_name"])
if is_32bit:
pack_format = "I"
bash_json_file = "bash32"
@@ -93,7 +90,6 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
("Command", str)],
self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)))
@@ -102,7 +98,6 @@ class Bash(plugins.PluginInterface, timeliner.TimeLinerInterface):
for row in self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)):
_depth, row_data = row
@@ -6,7 +6,7 @@ found in Linux's /proc file system."""
import logging
from typing import List
from volatility3.framework import exceptions, interfaces, contexts
from volatility3.framework import exceptions, interfaces
from volatility3.framework import renderers
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
@@ -18,15 +18,12 @@ vollog = logging.getLogger(__name__)
class Check_afinfo(plugins.PluginInterface):
"""Verifies the operation function pointers of network protocols."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols")
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
]
# returns whether the symbol is found within the kernel (system.map) or not
@@ -63,7 +60,8 @@ class Check_afinfo(plugins.PluginInterface):
yield var_name, "show", var.seq_show
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
op_members = vmlinux.get_type('file_operations').members
seq_members = vmlinux.get_type('seq_operations').members
@@ -4,7 +4,7 @@
import logging
from volatility3.framework import interfaces, renderers, constants
from volatility3.framework import interfaces, renderers
from volatility3.framework.configuration import requirements
from volatility3.plugins.linux import pslist
@@ -14,22 +14,19 @@ vollog = logging.getLogger(__name__)
class Check_creds(interfaces.plugins.PluginInterface):
"""Checks if any processes are sharing credential structures"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls):
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0))
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0))
]
def _generator(self):
# vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
type_task = self.context.symbol_space.get_type(self.config['vmlinux'] + constants.BANG + "task_struct")
type_task = vmlinux.get_type("task_struct")
if not type_task.has_member("cred"):
raise TypeError(
@@ -40,7 +37,7 @@ class Check_creds(interfaces.plugins.PluginInterface):
creds = {}
tasks = pslist.PsList.list_tasks(self.context, self.config['primary'], self.config['vmlinux'])
tasks = pslist.PsList.list_tasks(self.context, vmlinux.name)
for task in tasks:
@@ -5,7 +5,7 @@
import logging
from typing import List
from volatility3.framework import interfaces, renderers, contexts, symbols
from volatility3.framework import interfaces, renderers, symbols
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
from volatility3.framework.symbols import linux
@@ -17,32 +17,28 @@ vollog = logging.getLogger(__name__)
class Check_idt(interfaces.plugins.PluginInterface):
""" Checks if the IDT has been altered """
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (1, 0, 0)),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (1, 0, 0))
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (2, 0, 0)),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (2, 0, 0))
]
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux'])
modules = lsmod.Lsmod.list_modules(self.context, vmlinux.name)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'],
self.config['vmlinux'], modules)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, vmlinux.name, modules)
is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["vmlinux"])
is_32bit = not symbols.symbol_table_is_64bit(self.context, vmlinux.symbol_table_name)
idt_table_size = 256
address_mask = self.context.layers[self.config['primary']].address_mask
address_mask = self.context.layers[vmlinux.layer_name].address_mask
# hw handlers + system call
check_idxs = list(range(0, 20)) + [128]
@@ -65,7 +61,8 @@ class Check_idt(interfaces.plugins.PluginInterface):
table = vmlinux.object(object_type = 'array',
offset = addrs.vol.offset,
subtype = vmlinux.get_type(idt_type),
count = idt_table_size)
count = idt_table_size,
absolute = True)
for i in check_idxs:
ent = table[i]
@@ -88,7 +85,7 @@ class Check_idt(interfaces.plugins.PluginInterface):
idt_addr = idt_addr & address_mask
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, idt_addr)
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(vmlinux, handlers, idt_addr)
yield (0, [format_hints.Hex(i), format_hints.Hex(idt_addr), module_name, symbol_name])
@@ -5,7 +5,7 @@
import logging
from typing import List
from volatility3.framework import interfaces, renderers, exceptions, constants, contexts
from volatility3.framework import interfaces, renderers, exceptions, constants
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
from volatility3.framework.objects import utility
@@ -18,19 +18,19 @@ vollog = logging.getLogger(__name__)
class Check_modules(plugins.PluginInterface):
"""Compares module list to sysfs info, if available"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (1, 0, 0))
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (2, 0, 0))
]
def get_kset_modules(self, vmlinux):
@classmethod
def get_kset_modules(self, context: interfaces.context.ContextInterface, vmlinux_name: str):
vmlinux = context.modules[vmlinux_name]
try:
module_kset = vmlinux.object_from_symbol("module_kset")
@@ -44,12 +44,12 @@ class Check_modules(plugins.PluginInterface):
ret = {}
kobj_off = self.context.symbol_space.get_type(self.config['vmlinux'] + constants.BANG +
'module_kobject').relative_child_offset('kobj')
kobj_off = vmlinux.get_type('module_kobject').relative_child_offset('kobj')
for kobj in module_kset.list.to_list(vmlinux.name + constants.BANG + "kobject", "entry"):
for kobj in module_kset.list.to_list(vmlinux.symbol_table_name + constants.BANG + "kobject", "entry"):
mod_kobj = vmlinux.object(object_type = "module_kobject", offset = kobj.vol.offset - kobj_off)
mod_kobj = vmlinux.object(object_type = "module_kobject", offset = kobj.vol.offset - kobj_off,
absolute = True)
mod = mod_kobj.mod
@@ -60,13 +60,11 @@ class Check_modules(plugins.PluginInterface):
return ret
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
kset_modules = self.get_kset_modules(vmlinux)
kset_modules = self.get_kset_modules(self.context, self.config['vmlinux'])
lsmod_modules = set(
str(utility.array_to_string(modules.name))
for modules in lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux']))
for modules in lsmod.Lsmod.list_modules(self.context, self.config['vmlinux']))
for mod_name in set(kset_modules.keys()).difference(lsmod_modules):
yield (0, (format_hints.Hex(kset_modules[mod_name]), str(mod_name)))
@@ -6,7 +6,7 @@ found in Linux's /proc file system."""
import logging
from typing import List
from volatility3.framework import exceptions, interfaces, contexts
from volatility3.framework import exceptions, interfaces
from volatility3.framework import renderers, constants
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
@@ -25,24 +25,26 @@ except ImportError:
class Check_syscall(plugins.PluginInterface):
"""Check system call table for hooks."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols")
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
]
def _get_table_size_next_symbol(self, table_addr, ptr_sz, vmlinux):
"""Returns the size of the table based on the next symbol."""
ret = 0
sym_table = self.context.symbol_space[vmlinux.name]
sorted_symbols = sorted([(sym_table.get_symbol(sn).address, sn) for sn in sym_table.symbols])
symbol_list = []
for sn in vmlinux.symbols:
try:
# When requesting the symbol from the module, a full resolve is performed
symbol_list.append((vmlinux.get_symbol(sn).address, sn))
except exceptions.SymbolError:
pass
sorted_symbols = sorted(symbol_list)
sym_address = 0
@@ -62,7 +64,8 @@ class Check_syscall(plugins.PluginInterface):
accurate."""
return len(
[sym for sym in self.context.symbol_space[vmlinux.name].symbols if sym.startswith("__syscall_meta__")])
[sym for sym in self.context.symbol_space[vmlinux.symbol_table_name].symbols if
sym.startswith("__syscall_meta__")])
def _get_table_info_other(self, table_addr, ptr_sz, vmlinux):
table_size_meta = self._get_table_size_meta(vmlinux)
@@ -93,12 +96,12 @@ class Check_syscall(plugins.PluginInterface):
md = capstone.Cs(capstone.CS_ARCH_X86, mode)
try:
func_addr = self.context.symbol_space.get_symbol(vmlinux.name + constants.BANG + syscall_entry_func).address
func_addr = vmlinux.get_symbol(syscall_entry_func).address
except exceptions.SymbolError as e:
# if we can't find the disassemble function then bail and rely on a different method
return 0
data = self.context.layers.read(self.config['primary'], func_addr, 6)
data = self.context.layers.read(self.config['vmlinux.layer_name'], func_addr, 6)
for (address, size, mnemonic, op_str) in md.disasm_lite(data, func_addr):
if mnemonic == 'CMP':
@@ -108,7 +111,7 @@ class Check_syscall(plugins.PluginInterface):
return table_size
def _get_table_info(self, vmlinux, table_name, ptr_sz):
table_sym = self.context.symbol_space.get_symbol(vmlinux.name + constants.BANG + table_name)
table_sym = vmlinux.get_symbol(table_name)
table_size = self._get_table_info_disassembly(ptr_sz, vmlinux)
@@ -123,7 +126,7 @@ class Check_syscall(plugins.PluginInterface):
# TODO - add finding and parsing unistd.h once cached file enumeration is added
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
ptr_sz = vmlinux.get_type("pointer").size
if ptr_sz == 4:
@@ -143,7 +146,7 @@ class Check_syscall(plugins.PluginInterface):
# enabled in order to support 32 bit programs and libraries
# if the symbol isn't there then the support isn't in the kernel and so we skip it
try:
ia32_symbol = self.context.symbol_space.get_symbol(vmlinux.name + constants.BANG + "ia32_sys_call_table")
ia32_symbol = vmlinux.get_symbol("ia32_sys_call_table")
except exceptions.SymbolError:
ia32_symbol = None
@@ -161,7 +164,7 @@ class Check_syscall(plugins.PluginInterface):
if not call_addr:
continue
symbols = list(self.context.symbol_space.get_symbols_by_location(call_addr))
symbols = list(vmlinux.get_symbols_by_absolute_location(call_addr))
if len(symbols) > 0:
sym_name = str(symbols[0].split(constants.BANG)[1]) if constants.BANG in symbols[0] else \
+3 -7
View File
@@ -17,16 +17,13 @@ from volatility3.plugins.linux import pslist
class Elfs(plugins.PluginInterface):
"""Lists all memory mapped ELF files for all processes."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -59,6 +56,5 @@ class Elfs(plugins.PluginInterface):
("End", format_hints.Hex), ("File Path", str)],
self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)))
@@ -4,7 +4,7 @@
import logging
from volatility3.framework import interfaces, renderers, contexts, exceptions
from volatility3.framework import interfaces, renderers, exceptions
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
from volatility3.framework.symbols import linux
@@ -16,26 +16,22 @@ vollog = logging.getLogger(__name__)
class Keyboard_notifiers(interfaces.plugins.PluginInterface):
"""Parses the keyboard notifier call chain"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls):
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (1, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (1, 0, 0))
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (2, 0, 0))
]
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux'])
modules = lsmod.Lsmod.list_modules(self.context, vmlinux.name)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'],
self.config['vmlinux'], modules)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, vmlinux.name, modules)
try:
knl_addr = vmlinux.object_from_symbol("keyboard_notifier_list")
@@ -49,12 +45,12 @@ class Keyboard_notifiers(interfaces.plugins.PluginInterface):
"This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt."
)
knl = vmlinux.object(object_type = "atomic_notifier_head", offset = knl_addr.vol.offset)
knl = vmlinux.object(object_type = "atomic_notifier_head", offset = knl_addr.vol.offset, absolute = True)
for call_back in linux.LinuxUtilities.walk_internal_list(vmlinux, "notifier_block", "next", knl.head):
call_addr = call_back.notifier_call
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, call_addr)
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(vmlinux, handlers, call_addr)
yield (0, [format_hints.Hex(call_addr), module_name, symbol_name])
+7 -11
View File
@@ -7,7 +7,6 @@ found in Linux's /proc file system."""
import logging
from typing import List, Iterable
from volatility3.framework import contexts
from volatility3.framework import exceptions, renderers, constants, interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
@@ -20,21 +19,18 @@ vollog = logging.getLogger(__name__)
class Lsmod(plugins.PluginInterface):
"""Lists loaded kernel modules."""
_required_framework_version = (1, 0, 0)
_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols")
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
]
@classmethod
def list_modules(cls, context: interfaces.context.ContextInterface, layer_name: str,
vmlinux_symbols: str) -> Iterable[interfaces.objects.ObjectInterface]:
def list_modules(cls, context: interfaces.context.ContextInterface, vmlinux_module_name: str) -> Iterable[
interfaces.objects.ObjectInterface]:
"""Lists all the modules in the primary layer.
Args:
@@ -47,7 +43,7 @@ class Lsmod(plugins.PluginInterface):
This function will throw a SymbolError exception if kernel module support is not enabled.
"""
vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0)
vmlinux = context.modules[vmlinux_module_name]
modules = vmlinux.object_from_symbol(symbol_name = "modules").cast("list_head")
@@ -58,7 +54,7 @@ class Lsmod(plugins.PluginInterface):
def _generator(self):
try:
for module in self.list_modules(self.context, self.config['primary'], self.config['vmlinux']):
for module in self.list_modules(self.context, self.config['vmlinux']):
mod_size = module.get_init_size() + module.get_core_size()
+6 -8
View File
@@ -19,17 +19,14 @@ vollog = logging.getLogger(__name__)
class Lsof(plugins.PluginInterface):
"""Lists all memory maps for all processes."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (1, 0, 0)),
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -37,6 +34,8 @@ class Lsof(plugins.PluginInterface):
]
def _generator(self, tasks):
vmlinux = self.context.modules[self.config['vmlinux']]
symbol_table = None
for task in tasks:
if symbol_table is None:
@@ -57,6 +56,5 @@ class Lsof(plugins.PluginInterface):
return renderers.TreeGrid([("PID", int), ("Process", str), ("FD", int), ("Path", str)],
self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)))
@@ -15,16 +15,13 @@ from volatility3.plugins.linux import pslist
class Malfind(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -48,7 +45,8 @@ class Malfind(interfaces.plugins.PluginInterface):
def _generator(self, tasks):
# determine if we're on a 32 or 64 bit kernel
if self.context.symbol_space.get_type(self.config["vmlinux"] + constants.BANG + "pointer").size == 4:
if self.context.symbol_space.get_type(
self.config["vmlinux.symbol_table_name"] + constants.BANG + "pointer").size == 4:
is_32bit_arch = True
else:
is_32bit_arch = False
@@ -75,6 +73,5 @@ class Malfind(interfaces.plugins.PluginInterface):
("Disasm", interfaces.renderers.Disassembly)],
self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)))
+3 -7
View File
@@ -15,17 +15,14 @@ from volatility3.plugins.linux import pslist
class Maps(plugins.PluginInterface):
"""Lists all memory maps for all processes."""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls):
# Since we're calling the plugin, make sure we have the plugin's requirements
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (2, 0, 0)),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -68,6 +65,5 @@ class Maps(plugins.PluginInterface):
("File Path", str)],
self._generator(
pslist.PsList.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = filter_func)))
+7 -14
View File
@@ -1,10 +1,9 @@
# 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 typing import Callable, Iterable, List, Any
from volatility3.framework import renderers, interfaces, contexts
from volatility3.framework import renderers, interfaces
from volatility3.framework.configuration import requirements
from volatility3.framework.objects import utility
@@ -12,17 +11,14 @@ 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, 0, 0)
_required_framework_version = (1, 2, 0)
_version = (1, 0, 0)
_version = (2, 0, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.ModuleRequirement(name = 'vmlinux'),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
@@ -53,7 +49,6 @@ class PsList(interfaces.plugins.PluginInterface):
def _generator(self):
for task in self.list_tasks(self.context,
self.config['primary'],
self.config['vmlinux'],
filter_func = self.create_pid_filter(self.config.get('pid', None))):
pid = task.pid
@@ -67,20 +62,18 @@ class PsList(interfaces.plugins.PluginInterface):
def list_tasks(
cls,
context: interfaces.context.ContextInterface,
layer_name: str,
vmlinux_symbols: str,
vmlinux_module_name: str,
filter_func: Callable[[int], bool] = lambda _: False) -> Iterable[interfaces.objects.ObjectInterface]:
"""Lists all the tasks in the primary layer.
Args:
context: The context to retrieve required elements (layers, symbol tables) from
layer_name: The name of the layer on which to operate
vmlinux_symbols: The name of the table containing the kernel symbols
vmlinux_module_name: The name of the kernel module on which to operate
Yields:
Process objects
"""
vmlinux = contexts.Module(context, vmlinux_symbols, layer_name, 0)
vmlinux = context.modules[vmlinux_module_name]
init_task = vmlinux.object_from_symbol(symbol_name = "init_task")
@@ -10,8 +10,6 @@ class PsTree(pslist.PsList):
"""Plugin for listing processes in a tree based on their parent process
ID."""
_required_framework_version = (1, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._processes = {}
@@ -36,7 +34,8 @@ class PsTree(pslist.PsList):
def _generator(self):
"""Generates the."""
for proc in self.list_tasks(self.context, self.config['primary'], self.config['vmlinux']):
for proc in self.list_tasks(self.context, self.config['vmlinux.layer_name'],
self.config['vmlinux.symbol_table_name']):
self._processes[proc.pid] = proc
# Build the child/level maps
@@ -5,7 +5,7 @@
import logging
from typing import List
from volatility3.framework import interfaces, renderers, exceptions, constants, contexts
from volatility3.framework import interfaces, renderers, exceptions, constants
from volatility3.framework.configuration import requirements
from volatility3.framework.interfaces import plugins
from volatility3.framework.objects import utility
@@ -19,26 +19,22 @@ vollog = logging.getLogger(__name__)
class tty_check(plugins.PluginInterface):
"""Checks tty devices for hooks"""
_required_framework_version = (1, 0, 0)
_required_framework_version = (1, 2, 0)
@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
return [
requirements.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "vmlinux", description = "Linux kernel symbols"),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (1, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (1, 0, 0))
requirements.ModuleRequirement(name = 'vmlinux', architectures = ["Intel32", "Intel64"]),
requirements.PluginRequirement(name = 'lsmod', plugin = lsmod.Lsmod, version = (2, 0, 0)),
requirements.VersionRequirement(name = 'linuxutils', component = linux.LinuxUtilities, version = (2, 0, 0))
]
def _generator(self):
vmlinux = contexts.Module(self.context, self.config['vmlinux'], self.config['primary'], 0)
vmlinux = self.context.modules[self.config['vmlinux']]
modules = lsmod.Lsmod.list_modules(self.context, self.config['primary'], self.config['vmlinux'])
modules = lsmod.Lsmod.list_modules(self.context, vmlinux.name)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, self.config['primary'],
self.config['vmlinux'], modules)
handlers = linux.LinuxUtilities.generate_kernel_handler_info(self.context, vmlinux.name, modules)
try:
tty_drivers = vmlinux.object_from_symbol("tty_drivers").cast("list_head")
@@ -52,12 +48,12 @@ class tty_check(plugins.PluginInterface):
"This means you are either analyzing an unsupported kernel version or that your symbol table is corrupt."
)
for tty in tty_drivers.to_list(vmlinux.name + constants.BANG + "tty_driver", "tty_drivers"):
for tty in tty_drivers.to_list(vmlinux.symbol_table_name + constants.BANG + "tty_driver", "tty_drivers"):
try:
ttys = utility.array_of_pointers(tty.ttys.dereference(),
count = tty.num,
subtype = vmlinux.name + constants.BANG + "tty_struct",
subtype = vmlinux.symbol_table_name + constants.BANG + "tty_struct",
context = self.context)
except exceptions.PagedInvalidAddressException:
continue
@@ -71,7 +67,7 @@ class tty_check(plugins.PluginInterface):
recv_buf = tty_dev.ldisc.ops.receive_buf
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(self.context, handlers, recv_buf)
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(vmlinux, handlers, recv_buf)
yield (0, (name, format_hints.Hex(recv_buf), module_name, symbol_name))