volatility3 icon indicating copy to clipboard operation
volatility3 copied to clipboard

Windows.truecrypt.Passphrase plugin failed

Open NaftalidaCosta opened this issue 2 months ago • 1 comments

Describe the bug A clear and concise description of what the bug is.

I tried using the windows.truecrypt.Passphrase plugin to find encrypted disk password using volatility3 2.27.1 a this error appeared in command output.

Context Volatility Version: 2.27.1 Operating System: Parrots Security OS - HackTheBox Python Version: 3.11.2 Suspected Operating System:
Command: #vol -f Snapshot14_1061.vmem windows.truecrypt.Passphrase

To Reproduce Steps to reproduce the behavior:

  1. Use command '...'
  2. See error

Expected behavior A clear and concise description of what you expected to happen.

  • Show the passphrase

Example output Please copy and paste the text demonstrating the issue, ideally with verbose output turned on (vol.py -vvv ...).

WARNING  volatility3.framework.layers.vmware: No metadata file found alongside VMEM file. A VMSS or VMSN file may be required to correctly process a VMEM file. These should be placed in the same directory with the same file name, e.g. Snapshot14_1609164553061.vmem and Snapshot14_161.vmss.
Progress:  100.00		PDB scanning finished                        
Offset	Length	Password
Traceback (most recent call last):
  File "/usr/local/bin/vol", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/hackerone/volatility3/volatility3/cli/__init__.py", line 934, in main
    CommandLine().run()
  File "/home/hackerone/volatility3/volatility3/cli/__init__.py", line 522, in run
    renderer.render(grid)
  File "/home/hackerone/volatility3/volatility3/cli/text_renderer.py", line 329, in render
    grid.populate(visitor, outfd)
  File "/home/hackerone/volatility3/volatility3/framework/renderers/__init__.py", line 318, in populate
    for level, item in self._generator:
  File "/home/hackerone/volatility3/volatility3/framework/plugins/windows/truecrypt.py", line 137, in _generator
    for offset, password in self.scan_module(
  File "/home/hackerone/volatility3/volatility3/framework/plugins/windows/truecrypt.py", line 82, in scan_module
    raise ValueError("PE data section not DWORD-aligned!")
ValueError: PE data section not DWORD-aligned!  

Text is preferred to screenshots for searching and to talk about specific parts of the output.

Additional information Add any other information about the problem here.

NaftalidaCosta avatar Dec 10 '25 01:12 NaftalidaCosta

Are you attempting to solve a particular HTB room/challenge, or are you just using the the HTB flavour of Parrot? Do you have an accompanying vmss/vmsn file alongside your snapshot? Is it named exactly the same except for the extension? Can you show the contents of the truecrypt plugin (cat truecrypt.py) - there are some potential compatibility/config modifications you may need to make. Are you able to share the sample?

deeFIR avatar Dec 13 '25 01:12 deeFIR

Image *I'm not trying to complete a room on the HTB platform, I'm looking to complete a forensic investigation to complete a certification. I am using Virtual Machines, Parrot HackTheBox Security operating system iso. I don't have the vmss files.

Full Output:

┌─[root@parrot]─[/home/hackerone/volatility3/volatility3/framework/plugins/windows]
└──╼ #cat truecrypt.py 
# This file is Copyright 2024 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
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):
    """TrueCrypt Cached Passphrase Finder"""

    _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,
            ),
        ]

    def scan_module(
        self, module_base: int, layer_name: str
    ) -> Generator[Tuple[int, str], None, None]:
        """Scans the TrueCrypt kernel module for cached passphrases.

        Args:
            module_base: the module's DLL base
            layer_name: the name of the layer in which the module resides

        Generates:
            A tuple of the offset at which a password is found, and the password
        """
        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
        format = objects.DataFormatInfo(
            length=DWORD_SIZE_BYTES, byteorder="little", signed=True
        )
        int32 = objects.templates.ObjectTemplate(
            objects.Integer, pe_table_name + constants.BANG + "int", data_format=format
        )
        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:
            # TrueCrypt maximum password length is 64
            # (see TrueCrypt/Common/Password.h)
            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,
            )
            # TrueCrypt/Common/Password.c permits chars in the range
            # [0x20, 0x7F).
            if not all(0x20 <= c < 0x7F for c in passphrase):
                continue
            # TrueCrypt/Common/Password.h::Password struct is padded with
            # 3 zero bytes to keep 64-byte alignment.
            buf: objects.Bytes = self.context.object(
                pe_table_name + constants.BANG + "bytes",
                layer_name,
                offset + length + 1,  # +1 for '\0'-terminated password string
                length=3,
            )
            if any(buf):
                continue
            # Password found.
            yield offset, passphrase.decode(encoding="ascii")

    def _generator(self):
        kernel = self.context.modules[self.config["kernel"]]
        mods: Iterable[interfaces.objects.ObjectInterface] = (
            modules.Modules.list_modules(self.context, self.config["kernel"])
        )
        try:
            truecrypt_module_base = next(
                mod.DllBase
                for mod in mods
                if mod.BaseDllName.get_string().lower() == "truecrypt.sys"
            )
        except StopIteration:
            vollog.warning(
                "Truecrypt module not found in the modules list. Unable to proceed."
            )
            return

        for offset, password in self.scan_module(
            truecrypt_module_base, kernel.layer_name
        ):
            yield (0, (format_hints.Hex(offset), len(password), password))

    def run(self) -> renderers.TreeGrid:
        return renderers.TreeGrid(
            [
                ("Offset", format_hints.Hex),
                ("Length", int),
                ("Password", str),
            ],
            self._generator(),
        )

NaftalidaCosta avatar Dec 22 '25 02:12 NaftalidaCosta

Hey @NaftalidaCosta I faced the same error when doing a room on TryHackMe, I used Gemini Pro to fix the code, which fixed it and it's working for me now: Here's the fixed version: https://gist.github.com/vivxk/1c01ee25018dcee7ee7e22c236f376bb Replace it with truecrypt.py under : volatility3/volatility3/framework/plugins/windows/truecrypt.py

vivxk avatar Jan 03 '26 16:01 vivxk

@vivxk Thanks for that I really appreciate your help. Can I share your respository?

vol -f /home/hackerone/volatility3memory/Snapshot14_1061.vmem windows.truecrypt.Passphrase
Volatility 3 Framework 2.27.1
WARNING  volatility3.framework.layers.vmware: No metadata file found alongside VMEM file. A VMSS or VMSN file may be required to correctly process a VMEM file. These should be placed in the same directory with the same file name, e.g. Snapshot14_1061.vmem and Snapshot14_1061.vmss.
Progress:  100.00		PDB scanning finished                        
Offset	  Length	  Password

5xf9500512dee2	8     superman

NaftalidaCosta avatar Jan 03 '26 19:01 NaftalidaCosta

Sure @NaftalidaCosta

vivxk avatar Jan 04 '26 17:01 vivxk