Init. commit
This commit is contained in:
185
HumanAI-Forensic-Hard/scripts/veracrypt.py
Normal file
185
HumanAI-Forensic-Hard/scripts/veracrypt.py
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
import logging
|
||||
from typing import Generator, Iterable, List, Tuple
|
||||
|
||||
from volatility3.framework import constants, interfaces, objects, renderers
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.interfaces import configuration
|
||||
from volatility3.framework.objects.utility import array_to_string
|
||||
from volatility3.framework.renderers import format_hints
|
||||
from volatility3.framework.symbols import intermed
|
||||
from volatility3.framework.symbols.windows.extensions import pe
|
||||
from volatility3.plugins.windows import modules
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Passphrase(interfaces.plugins.PluginInterface):
|
||||
"""VeraCrypt/TrueCrypt cached passphrase finder (driver .data scan)."""
|
||||
|
||||
_version = (0, 1, 0)
|
||||
_required_framework_version = (2, 5, 2)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls) -> List[configuration.RequirementInterface]:
|
||||
return [
|
||||
requirements.ModuleRequirement(
|
||||
"kernel",
|
||||
description="Windows kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="modules", component=modules.Modules, version=(3, 0, 0)
|
||||
),
|
||||
requirements.IntRequirement(
|
||||
name="min-length",
|
||||
description="Minimum length of passphrases to identify",
|
||||
default=5,
|
||||
optional=True,
|
||||
),
|
||||
requirements.StringRequirement(
|
||||
name="driver",
|
||||
description=(
|
||||
"Driver name substring to scan (case-insensitive), "
|
||||
"e.g. 'veracrypt', 'veracrypt-x64.sys', 'truecrypt.sys'"
|
||||
),
|
||||
default="veracrypt",
|
||||
optional=True,
|
||||
),
|
||||
]
|
||||
|
||||
def scan_module(
|
||||
self, module_base: int, layer_name: str
|
||||
) -> Generator[Tuple[int, str], None, None]:
|
||||
pe_table_name = intermed.IntermediateSymbolTable.create(
|
||||
self.context, self.config_path, "windows", "pe", class_types=pe.class_types
|
||||
)
|
||||
dos_header: pe.IMAGE_DOS_HEADER = self.context.object(
|
||||
pe_table_name + constants.BANG + "_IMAGE_DOS_HEADER",
|
||||
layer_name,
|
||||
module_base,
|
||||
)
|
||||
|
||||
data_section: objects.StructType = next(
|
||||
sec
|
||||
for sec in dos_header.get_nt_header().get_sections()
|
||||
if array_to_string(sec.Name) == ".data"
|
||||
)
|
||||
base: int = data_section.VirtualAddress + module_base
|
||||
size: int = data_section.Misc.VirtualSize
|
||||
|
||||
# Looking at `Length` in TrueCrypt/Common/Password.h::Password struct
|
||||
DWORD_SIZE_BYTES: int = 4
|
||||
fmt = objects.DataFormatInfo(
|
||||
length=DWORD_SIZE_BYTES, byteorder="little", signed=True
|
||||
)
|
||||
int32 = objects.templates.ObjectTemplate(
|
||||
objects.Integer, pe_table_name + constants.BANG + "int", data_format=fmt
|
||||
)
|
||||
count, not_aligned = divmod(size, DWORD_SIZE_BYTES)
|
||||
if not_aligned:
|
||||
raise ValueError("PE data section not DWORD-aligned!")
|
||||
|
||||
lengths = self.context.object(
|
||||
pe_table_name + constants.BANG + "array",
|
||||
layer_name,
|
||||
base,
|
||||
count=count,
|
||||
subtype=int32,
|
||||
)
|
||||
|
||||
min_length = self.config.get("min-length")
|
||||
for length in lengths:
|
||||
|
||||
if not min_length <= length <= 64:
|
||||
continue
|
||||
|
||||
offset = length.vol["offset"] + DWORD_SIZE_BYTES
|
||||
passphrase: objects.Bytes = self.context.object(
|
||||
pe_table_name + constants.BANG + "bytes",
|
||||
layer_name,
|
||||
offset,
|
||||
length=length,
|
||||
)
|
||||
|
||||
|
||||
if not all(0x20 <= c < 0x7F for c in passphrase):
|
||||
continue
|
||||
|
||||
buf: objects.Bytes = self.context.object(
|
||||
pe_table_name + constants.BANG + "bytes",
|
||||
layer_name,
|
||||
offset + length + 1,
|
||||
length=3,
|
||||
)
|
||||
if any(buf):
|
||||
continue
|
||||
|
||||
yield offset, passphrase.decode(encoding="ascii")
|
||||
|
||||
def _find_driver_bases(
|
||||
self, mods: Iterable[interfaces.objects.ObjectInterface]
|
||||
) -> List[int]:
|
||||
driver_substr = (self.config.get("driver") or "").lower().strip()
|
||||
|
||||
def matches(mod_name: str, needle: str) -> bool:
|
||||
return needle and needle in mod_name
|
||||
|
||||
def bases_for(needle: str) -> List[int]:
|
||||
out: List[int] = []
|
||||
for mod in mods:
|
||||
try:
|
||||
name = mod.BaseDllName.get_string().lower()
|
||||
except Exception:
|
||||
continue
|
||||
if matches(name, needle):
|
||||
out.append(int(mod.DllBase))
|
||||
return out
|
||||
|
||||
if driver_substr:
|
||||
bases = bases_for(driver_substr)
|
||||
if bases:
|
||||
return bases
|
||||
|
||||
for needle in ("veracrypt", "truecrypt"):
|
||||
bases = bases_for(needle)
|
||||
if bases:
|
||||
return bases
|
||||
|
||||
return []
|
||||
|
||||
def _generator(self):
|
||||
kernel = self.context.modules[self.config["kernel"]]
|
||||
mods: Iterable[interfaces.objects.ObjectInterface] = modules.Modules.list_modules(
|
||||
self.context, self.config["kernel"]
|
||||
)
|
||||
|
||||
driver_bases = self._find_driver_bases(mods)
|
||||
if not driver_bases:
|
||||
vollog.warning(
|
||||
"No VeraCrypt driver module found in the modules list. Unable to proceed."
|
||||
)
|
||||
return
|
||||
|
||||
seen = set()
|
||||
for module_base in driver_bases:
|
||||
try:
|
||||
for offset, password in self.scan_module(module_base, kernel.layer_name):
|
||||
key = (offset, password)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
yield (0, (format_hints.Hex(offset), len(password), password))
|
||||
except Exception as exc:
|
||||
vollog.debug("Failed scanning module at 0x%x: %s", module_base, exc)
|
||||
|
||||
def run(self) -> renderers.TreeGrid:
|
||||
return renderers.TreeGrid(
|
||||
[
|
||||
("Offset", format_hints.Hex),
|
||||
("Length", int),
|
||||
("Password", str),
|
||||
],
|
||||
self._generator(),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user