Files
volatility3/volatility/framework/plugins/windows/privileges.py
T

100 lines
4.8 KiB
Python

# 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
import logging
import os, json
from typing import Callable, List, Generator, Iterable
from volatility.framework import renderers, interfaces, objects, exceptions, constants
from volatility.framework.configuration import requirements
from volatility.framework.objects import utility
from volatility.framework.renderers import format_hints
from volatility.plugins.windows import pslist
vollog = logging.getLogger(__name__)
class Privs(interfaces.plugins.PluginInterface):
"""Lists process token privileges"""
_version = (1, 0, 0)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Find the sids json path (or raise error if its not in the plugin directory).
for plugin_dir in constants.PLUGINS_PATH:
sids_json_file_name = os.path.join(plugin_dir, os.path.join("windows", "sids_and_privileges.json"))
if os.path.exists(sids_json_file_name):
break
else:
vollog.log(constants.LOGLEVEL_VVV, 'sids_and_privileges.json file is missing plugin error')
raise RuntimeError("The sids_and_privileges.json file missed from you plugin directory")
# Get service sids dictionary (we need only the service sids).
with open(sids_json_file_name, 'r') as file_handle:
temp_json = json.load(file_handle)['privileges']
self.privilege_info = {int(priv_num):temp_json[priv_num] for priv_num in temp_json}
@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.TranslationLayerRequirement(name = 'primary',
description = 'Memory layer for the kernel',
architectures = ["Intel32", "Intel64"]),
requirements.SymbolTableRequirement(name = "nt_symbols", description = "Windows kernel symbols"),
requirements.ListRequirement(name = 'pid',
description = 'Filter on specific process IDs',
element_type = int,
optional = True),
requirements.PluginRequirement(name = 'pslist', plugin = pslist.PsList, version = (1, 0, 0)),
]
def _generator(self, procs):
for task in procs:
try:
process_token = task.Token.dereference().cast("_TOKEN")
except exceptions.InvalidAddressException:
vollog.log(constants.LOGLEVEL_VVV, 'Skeep invalid token.')
continue
for value, present, enabled, default in process_token.privileges():
# Skip privileges whose bit positions cannot be
# translated to a privilege name
if not self.privilege_info.get(int(value)):
vollog.log(constants.LOGLEVEL_VVV, 'Skeep invalid privilege ({}).'.format(value))
continue
name, desc = self.privilege_info.get(int(value))
# Set the attributes
attributes = []
if present:
attributes.append("Present")
if enabled:
attributes.append("Enabled")
if default:
attributes.append("Default")
yield (0,
[int(task.UniqueProcessId),
objects.utility.array_to_string(task.ImageFileName),
int(value),
str(name),
",".join(attributes),
str(desc)])
def run(self):
filter_func = pslist.PsList.create_pid_filter(self.config.get('pid', None))
return renderers.TreeGrid([("PID", int), ("Process", str), ("Value", int), ("Privilege", str),
("Attributes", str), ("Description", str)],
self._generator(
pslist.PsList.list_processes(context = self.context,
layer_name = self.config['primary'],
symbol_table = self.config['nt_symbols'],
filter_func = filter_func)))