Extraction of passwords from memory: how master keys of password managers settle in the RAM-dump

Depov

Activist
ULTIMATE
SUPREME
PREMIUM
MEMBER
Joined
Feb 18, 2025
Messages
126
Reaction score
115
Deposit
0$
On one IR case in a fintech company, we shot the RAM dump via WinPmem - RAT at the developer's workstation found on Thursday morning, the full memory image began four hours after the start of the response. Bitwarden was blocked by car: the user handled the storage two hours before we arrived. The master-password of 24 characters lay in the heap segment of the Bitwarden.exe process in the open form. Two hours after blocking, no interaction with the application - and the password phrase is read through strings without a single transformation. CVE-2023-38840. That case determined how we are now building monitoring password managers on endpoints.
A place in kill chain: why the attacker dump memory of the password manager
Password manager is the golden goal of post-exploitation. Damp LSASS (T1003.001, Credential Access) gives hasheshes of the current machine. Extraction of passwords from the memory of the manager (T1555.005, Credential Access) opens access to everything that the user stores in the store: corporate SaaS, VPN configurations, API keys, SSH certificates, cloud consoles accounting. The difference is between one key from the apartment and the bundle of the entire building.

Attack chain:
1. Initial Access - spearphishing, drive-by, compromising supply chain
2. Persistence - RAT is fixed on the host
3. Discovery (T1057) )- process reproach, search Bitwarden.exe, KeePass.exe, 1Password.exe
4. Credential Access (T1555T1555.005.005) - reading the memory of the target process or minidump
5. Collection (T1005) )- parallel collection of storage files (.kdbx, data.json)
6. Exfiltration - output of master password and storage files on C2
The vector that is often overlooked is an insider or compromised legitimate host. The attacker, moving over the network via the email movement, gets on a car with a running password manager - the process dump takes one command (procdump, Task Manager "Create Dump File", etc.). For SOC, this means that you need to monitor not only external threats, but also the atypical use of legitimate utility on internal hosts.

Financial logic for the Blue Team is transparent: one compromised manager’s accounting is not one accounting, but dozens to hundreds of services. A typical scenario from investigations: the attacker extracts the master password Bitwarden from the dump, deciphers vault from %AppData%\Bitwarden\data.json, logs in to the cloud console through IAM-regulation from the storage and creates a backdoor user. From the dump to fixation in the cloud - less than an hour. For companies under regulatory requirements, this is a direct path to negotiable fines for data leakage.
Memory forensics of password managers: what remains in RAM
The key question for the DFIR-analyst when analyzing the memory of the password manager processes: what remains in the RAM after the introduction of the master password, and what of this is experiencing the blocking of the storage?
Bitwarden: master password from memory and CVE-2023-38840
Bitwarden Desktop is built on Electron - under the Chromium hood with V8 engine. Each functional part works in a separate child process. When analyzing the dump, look for the process Bitware.exe with argument --no-zygote in the command line - it is this rendering process that caches sensitive data. For web extension in Chrome/Edge - process with --extension-process, but there the vulnerability was closed earlier than in the desktop client.

The root of the problem is the architecture of the V8. JavaScript strings are immutable: you can not overwrite the contents of the string with zeros, you can only nullify the link to it. When blocking the storage, Bitwarden reset the variable with the password, but the line itself remained in the weap V8. The V8 garbage collector when releasing memory does not rip off the contents - the password bytes are at the same address until the allocator reuses the area under another object. In fact, “block” is to throw the key from the safe, but leave the safe open.

CVE-2023-38840 - CVSS 5.5 (MEDIUM). Vector: CVSS:3.1/AV:L/AV:L/L/IN::L/UI::C/I::N/A:N. Key components: local access (AV:L), low complexity (AC:L), minimum privileges (PR:L), user action is not required (UI:N), confidentiality is full compromising (C:H). Vulnerable Bitwarden Desktop version 2023.7.0 and below.

According to the Hexiosec study, the master password in the memory of the render-process was preceded by a stable hex prefix. The exact format depends on the internal representation of V8 (SeqOneByteString vs SeqTwoByteString): 04 00 00 00 [длина] 00 00 00 01 [3 байта] [байты пароля] - approximate diagram where the fifth byte encodes the length of the string (for example, 0x14 for 20 ASCII symbols in SeqOneBtesString). The first four bytes and bytes 7-9 remained stable even after the reboot. Hexiosec has created a PoC-tool BW-dump (tested on Bitwarden Desktop 2023.2.0) to automate the master password on Windows via Windows API for reading the memory of the target process.

The patch closed the vulnerability in versions above 2023.7.0 (the 2023.7.0 itself remains vulnerable). But here’s the important thing: with an unlocked vault, all vault records are in memory in a decrypted form. This is confirmed in the discussion at Bitwarden Community: "When the vault is unlocked, all of the vault contents exist in a decrypted state in the process memory""When the safe is unlocked, the entire status of the safe exists in the memory of the process in uncompuried form". Architectural inevitability - the application can not show the password without decrypting it.
KeePass: master-password from memory through . NET heap
KeePass is written on . NET and uses SecureString, the contents of which are encrypted in the process memory (on Windows - via DPAPI / ProtectedMemory). On paper, it's secure. In practice - with reservations that for memory forensics change everything.

CVE-2023-32784 (CVSS 7.5, HIGH): in KeePass 2.x to version 2.54, the master password (except the first symbol) is restored from the memory dump, even if the storage is blocked or the process is complete. Root cause - vulnerability in SecureTextBoxex: with the bellite of password entering into the masked field, each typed symbol generated a managed-line of residues (•a, ••ab, ••ab), which remained in the sueda heap. NET and allowed to restore the password from the second symbol. It has nothing to do with SecureString -> System.String Conversion for KDF - that mechanism poses a separate architectural risk.

In addition CVE-2023-32784, there is a common architectural problem: when entering the master password KeePass deciphers SecureString in the usual System.String for cryptographic operations - damming the key, checking the integrity of the base. At this point, the memory dump of the master-password will show the manual in the heap. NET. Compacting GC. NET moves objects: it copies the string to the new address for defragmentation, and the old area does not nullify. The result is several copies of the master password in heap, none is cleaned. If when analyzing the dump, the password is not the expected displacement - look for a pile in the "dead" areas, where GC moved the original. GC as an unwitting password archiver is an irony that developers. The NET was clearly not laid.

Each entry to which the user applied for the session remains in the memory of the process in a decrypted form. According to the 2019 ISE report, referred to by Bitwarden Community members, this is confirmed for KeePass, 1Password and Dashlane.

Password Manager Forensics (PMF), developed by Sascha Hähni (repository shaehni/password-manager-forensics on GitHub), automates the extraction of artifacts from Bitwarden and KeePass on Windows. PPM implements a four-stage process: the identification of the manager’s files, extract the master password from the memory dump, the configuration parsing, decryption of the forensics password storage in a compatible way with validation. If the master password cannot be pulled out of the dump - the PMF goes to the drothesp of the PIN or short password.
Comparison of Memory Protection Approaches
1781473780981.png

1Password data is based on the ISE 2019 report – current versions with Rust components could seriously improve memory work. For the current state, independent verification is required.
Extracting password storage from RAM: practice
Adjustments to the environment:
• Target machine: Windows 10/11 or Windows Server 2016+
• Analyst Machine: Windows or GNU/Linux, Python 3.8+
• RAM analytics: at least 8 GB; for processing dumps with a volume of more than 4 GB - 16 GB
• Tools: WinPem (removal of the full RAM dump), procdump (Syinternals, the dam of a particular process), Volatility 3 (image analysis), YARA 4.x (pattern-matchining)
• Disc: volume RAM target machine + 20% stock
Deleting the Damp and Memory Analysis of Password Manager Processes
Timing is critical: the longer the machine works after the incident, the more likely it is to overwrite the memory area with a password - GC V8 or . NET will move the object, and the new allocation will expend the old bytes. Remove the dump at the first opportunity. Every minute works against you.

Two approaches depending on the task. Full image of RAM through winpmem_mini_x64.exe output.raw - makes it possible to analyze all processes and reconstruct the picture. Target Damp through procdump -ma <PID> bw_dump.dmp - faster and more compact, but lose the context of other processes. PID of the desired child process (s --no-zygote) is determined through wmic process where "name='Bitwarden.exe'" get ProcessId,CommandLine.

Primary Triozh - strings -el Unicode Little Endian with the search for markers: user email (Bitwarden login), file name .kdbx (KeePass), fragments of the URL of the repository. The presence of markers confirms the artifacts of the password manager in the dump and narrows the search area.

In Volatility 3 start with vol -f memdump.raw windows.pslist - find the PID process of the manager and his child processes. For Bitwarden Desktop search for daughters with --no-zygote in the command line - it contains sensitive data.
YARA-patterns for Search Automation
To automate the search for the master password Bitwarden in the memory dump - YARA-rule based on a hexex prefix from the Hexiosec study:
Code:
rule bitwarden_master_pwd_heap {
meta:
description = "Bitwarden Desktop master pwd prefix"
cve = "CVE-2023-38840"
strings:
$prefix = { 04 00 00 00 ?? 00 00 00 01 ?? ?? ?? }
condition:
$prefix
}
The rule gives false positives - a pattern of 12 bytes is not unique in an arbitrary dump. But as a triage tool, it narrows the search area from gigabytes to dozens of displacements, each of which is checked manually. Combine with check: bytes after $prefix must contain printed characters with a length equal to the value of the fifth byte.

Restriction: Pattern confirmed for Bitwarden Desktop until 20237.0. In patched versions, the master password is cleared when blocking - this method is not applicable.

There is no stable hex prefix for KeePass. Works more efficiently strings -el with filtration in the vicinity of the markers KeePass - lines "KeePass", ".kdbx", "ProtectedBin".
 
Top Bottom