typeanalysisfamilyunclassified-msvc-browser-credential-harvesterconfidencelowpeinfostealercompilerc2persistencedefense-evasiondiscoverycredential-accessmitre-attck
SHA-256: 9d3d5ac032a3d26671c21b3b8832c46785f30523b3631ff2d59d5eaf3494d661

unclassified-msvc-browser-credential-harvester: 9d3d5ac0 — MSVC 14.50 x64 DLL with Chrome App-Bound Encryption bypass, SQLite 3.49.1, Bootstrap reflective loader

Executive Summary

A 1.02 MB MSVC 14.50 x64 DLL compiled in April 2026. Single export Bootstrap at 0x18002FA88. No packing, no obfuscation, no Authenticode signature. Statically links SQLite 3.49.1 and carries a full browser-credential harvesting toolchain targeting Chrome, Brave, Edge, and Firefox. Notable for explicit handling of Chrome's newer App-Bound Encryption (ABE) (app_bound_encrypted_key, ASTER_KEY:) with a graceful fallback to legacy DPAPI. No network APIs in the IAT — this is a pure extraction module; exfiltration is handled by a separate stage. Static-only analysis (CAPE skipped — no Windows guest).

What It Is

Field Value
SHA-256 9d3d5ac032a3d26671c21b3b8832c46785f30523b3631ff2d59d5eaf3494d661
File type PE32+ executable (DLL) (GUI) x86-64, 6 sections ^[file.txt]
Size 1,047,040 bytes (1.02 MB)
Compiler MSVC 14.50 (Visual Studio 2022) ^[exiftool.json]
Timestamp Wed Apr 22 05:56:01 2026 UTC ^[pefile.txt:38]
Signed No ^[rabin2-info.txt]
Packing None
Sections .text (code, entropy 6.57), .data, .pdata, .idata, .fptable (entropy 0.0), .reloc ^[pefile.txt:79-199]
Entry point 0x1800E3F5C ( falls inside .text) ^[pefile.txt:54]
Export Bootstrap @ 0x18002FA88 (1 function, 1 name) ^[pefile.txt:267-268]
Debug IMAGE_DEBUG_TYPE_POGO (Profile-Guided Optimization) ^[pefile.txt:575]
GuardCF Enabled (SecurityCookie, GuardCFCheckFunctionPointer) ^[pefile.txt:528-532]
PIC Yes (pic: true in rabin2) ^[rabin2-info.txt]
SQLite 3.49.1 statically linked (source ID 873d4e274b...) ^[strings.txt:1474]

How It Works

The binary is a browser credential extraction module designed to be loaded reflectively (the Bootstrap export) or via normal DLL load. It does not contain any network exfiltration logic — it writes harvested data to JSON files on disk (fingerprint.json, cookies.json, passwords.json, etc.) and relies on a companion stage for upload.

Browser Targeting

Strings reveal deep Chrome/Brave/Edge knowledge ^[strings.txt:249-314]:

  • Chrome, Brave-Browser, Microsoft\Browser, chrome, chrome-beta
  • User Data, Local State, Default, Preferences, Extensions
  • Login Data, Login Data For Account, Cookies, Web Data
  • Network, autofill, credentials_enable_service, safebrowsing

App-Bound Encryption Bypass

This is the distinguishing capability. Chrome 127+ introduced App-Bound Encryption to protect Local State keys even from Local System. This sample explicitly handles both paths:

  • app_bound_encrypted_key — the new ABE field in Chrome Local State ^[strings.txt:328]
  • aster_app_bound_encrypted_key — variant/prefixed field name ^[strings.txt:332]
  • ASTER_KEY: — debug/log prefix for decrypted ABE key material ^[strings.txt:333]
  • NO_ABE:Browser uses legacy DPAPI encryption (App-Bound Encryption not enabled) — graceful fallback path ^[strings.txt:330]

The presence of both ABE and DPAPI fallback strings, plus DecryptData failed: 0x ^[strings.txt:341], indicates a two-path decryption routine: try ABE first, fall back to CryptUnprotectData (implied by DPAPI references and CoInitializeEx for COM interop).

SQLite Aggregation

The binary embeds the full SQLite 3.49.1 engine (source ID 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70) ^[strings.txt:1474]. It uses SQLite to query browser databases:

  • Cookies: SELECT host_key, name, path, is_secure, is_httponly, expires_utc, encrypted_value FROM cookies ^[strings.txt:360]
  • Passwords: SELECT origin_url, username_value, password_value FROM logins ^[strings.txt:369]
  • Cards: SELECT guid, name_on_card, expiration_month, expiration_year, card_number_encrypted FROM credit_cards ^[strings.txt:375]
  • IBANs: SELECT value_encrypted, nickname FROM local_ibans ^[strings.txt:382]
  • Tokens: SELECT service, encrypted_token, binding_key FROM token_service ^[strings.txt:386]

Fingerprinting

Before extraction, the binary builds a fingerprint.json containing:

  • Browser version, executable path, user data path
  • Profile count, computer name, Windows user
  • OS version (via RtlGetVersion) ^[strings.txt:317]
  • Architecture
  • Sync status, enterprise management, update channel
  • Default search engine, hardware acceleration, metrics, autofill, password manager, safe browsing, DNT, third-party cookie blocking, translate status ^[strings.txt:260-306]

Output Files

Harvested data is written to:

  • fingerprint.json
  • cookies.json
  • passwords.json
  • passwords_account.json
  • cards.json
  • iban.json
  • tokens.json ^[strings.txt:353-359]

Anti-Analysis

Minimal but present:

  • IsDebuggerPresent ^[pefile.txt:471]
  • QueryPerformanceCounter + GetTickCount timing ^[pefile.txt:451-452]
  • CreateMutexW for single-instance gating ^[pefile.txt:414]
  • No VM-specific checks observed

Decompiled Behavior

Bootstrap Export (0x18002FA88)

Radare2 decompilation of sym.chrome_decrypt.dll_Bootstrap reveals a reflective-loader stub nested inside a legitimate MSVC DLL ^[r2:sym.chrome_decrypt.dll_Bootstrap]:

  1. PE validation: checks MZ (0x5A4D) and PE (0x4550) signatures at the module base.
  2. PEB walking: reads gs:[0x60] (PEB), follows +0x18 (LDR), then +0x20 (InMemoryOrderModuleList) to enumerate loaded modules.
  3. Export hash resolution: iterates exports with ror r9d, 0xD (ROR13 hash algorithm), comparing against hardcoded hashes 0x6a4abc5b and 0x3cfa685d.
  4. API pointer caching: resolved function pointers stored in a local stack array ([rbp + rbx*8 - 0x80]).

This is a classic position-independent shellcode pattern, suggesting the Bootstrap export is designed for injection scenarios where the Windows loader has not fixed the IAT. The DLL's normal import table (100+ APIs) is available for non-injected use.

Import Surface

Cryptography / DPAPI:

  • bcrypt.dll: BCryptOpenAlgorithmProvider, BCryptGenerateSymmetricKey, BCryptDecrypt, BCryptDestroyKey, BCryptSetProperty, BCryptCloseAlgorithmProvider ^[pefile.txt:280-285]
  • CRYPT32.dll: CryptStringToBinaryA (Base64 decode) ^[pefile.txt:343]

COM / OLE (for DPAPI and browser interop):

  • ole32.dll: CoInitializeEx, CoCreateInstance, CoSetProxyBlanket, CoUninitialize, CoTaskMemFree ^[pefile.txt:295-299]
  • OLEAUT32.dll: SysAllocStringByteLen, SysFreeString, SysStringByteLen (by ordinal) ^[pefile.txt:309-311]

System / Process:

  • CreateThread, CreateToolhelp32Snapshot, Process32FirstW, Process32NextW, TerminateThread ^[pefile.txt:379-396]
  • VirtualProtect, CreateFileMappingW, MapViewOfFile, UnmapViewOfFile ^[pefile.txt:417-450]
  • GetUserNameA, GetComputerNameA, RtlGetVersion, GetNativeSystemInfo ^[pefile.txt:353,382,378]
  • SHGetKnownFolderPath (for locating browser profile directories) ^[pefile.txt:321]

File / Mutex:

  • CreateMutexW, WaitForSingleObject, WaitForSingleObjectEx ^[pefile.txt:390,414,429]
  • CreateFileW/A, ReadFile, WriteFile, DeleteFileW/A, SetEndOfFile, SetFilePointer ^[pefile.txt:385-428]

No WinInet, WinHTTP, WS2_32, URLMon, or SMTP APIs are imported. Exfiltration is not this module's job.

C2 Infrastructure

None recoverable from static analysis.

No hardcoded domains, IPs, URLs, webhooks, or paste sites. No network imports. The binary writes harvested data to local JSON files and expects a companion stage to handle exfiltration. This is a deliberate separation of concerns: the harvester stays small and focused, while the downloader/exfiltrator carries the network risk.

Interesting Tidbits

  • The ASTER_KEY prefix (ASTER_KEY:) is unique in this corpus. It may be a developer handle, a project codename, or simply a prefix chosen to avoid collisions. No other sample in the wiki references it. ^[strings.txt:333]
  • .fptable section with entropy 0.0 suggests a pre-computed float lookup table — possibly for fast entropy calculations or crypto operations. ^[pefile.txt:162-179]
  • SQLite 3.49.1 is very recent (Feb 2025 source ID). The malware author rebuilt SQLite from source or linked a static library from a recent distribution. ^[strings.txt:1474]
  • chrome_decrypt.dll as the module name in the export directory is unusually honest for malware. It advertises its purpose. ^[pefile.txt:268]
  • No wallet/crypto strings — this is a browser credential harvester, not a crypto-wallet clipper. The focus is on cookies, passwords, saved cards, and IBANs.
  • GuardCF enabled — unusual for malware; adds legitimate software camouflage and complicates certain hooking techniques.

How To Mess With It (Homelab Replication)

Toolchain

  • Visual Studio 2022 (MSVC 14.50)
  • Target: x64 DLL, Windows GUI subsystem
  • Link SQLite 3.49.1 statically (amalgamation build)
  • Enable GuardCF (/guard:cf) and POGO (/genprofile or /fastgenprofile)

Key APIs to Replicate

  • CoInitializeEx + CoCreateInstance for DPAPI COM interop
  • BCryptOpenAlgorithmProvider (AES-GCM or AES-CBC) for decrypting ABE-protected keys
  • CryptStringToBinaryA for Base64 decoding of app_bound_encrypted_key
  • SHGetKnownFolderPath (FOLDERID_LocalAppData, FOLDERID_Profile) to locate browser profiles
  • CreateToolhelp32Snapshot to enumerate browser processes
  • CreateMutexW for single-instance gating

Verification

  1. Build a test DLL with a Bootstrap export
  2. Place a Chrome Local State with ABE enabled in a test profile
  3. Call Bootstrap; check if it produces fingerprint.json and cookies.json
  4. Verify ASTER_KEY: appears in debug output when ABE is present, and NO_ABE when absent

Deployable Signatures

YARA Rule

rule unclassified_msvc_browser_credential_harvester
{
    meta:
        description = "MSVC x64 DLL browser credential harvester with Chrome ABE bypass"
        author = "PacketPursuit"
        date = "2026-08-08"
        hash = "9d3d5ac032a3d26671c21b3b8832c46785f30523b3631ff2d59d5eaf3494d661"

    strings:
        $a1 = "ASTER_KEY:" ascii wide
        $a2 = "aster_app_bound_encrypted_key" ascii wide
        $a3 = "app_bound_encrypted_key" ascii wide
        $a4 = "NO_ABE:Browser uses legacy DPAPI encryption (App-Bound Encryption not enabled)" ascii wide
        $a5 = "chrome_decrypt.dll" ascii wide
        $a6 = "fingerprint.json" ascii wide
        $a7 = "DecryptData failed: 0x" ascii wide

        $b1 = "SELECT host_key, name, path, is_secure, is_httponly, expires_utc, encrypted_value FROM cookies" ascii wide
        $b2 = "SELECT origin_url, username_value, password_value FROM logins" ascii wide
        $b3 = "SELECT guid, name_on_card, expiration_month, expiration_year, card_number_encrypted FROM credit_cards" ascii wide
        $b4 = "SELECT value_encrypted, nickname FROM local_ibans" ascii wide
        $b5 = "SELECT service, encrypted_token, binding_key FROM token_service" ascii wide

        $c1 = "SQLite format 3" ascii
        $c2 = "COMPILER=msvc-1950" ascii

    condition:
        uint16(0) == 0x5A4D and
        uint32(uint32(0x3C)) == 0x00004550 and
        (pe.machine == pe.MACHINE_AMD64 or pe.machine == pe.MACHINE_IA64) and
        pe.exports("Bootstrap") and
        (2 of ($a*) or 3 of ($b*)) and
        $c1 and $c2
}

Sigma Rule

title: Browser Credential Harvester Module Execution
status: experimental
description: Detects execution of a DLL with chrome_decrypt.dll export and browser credential harvesting behavior
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        - Image|endswith: 'chrome_decrypt.dll'
        - CommandLine|contains:
            - 'Bootstrap'
            - 'chrome_decrypt'
    selection_file:
        - TargetFilename|endswith:
            - 'fingerprint.json'
            - 'cookies.json'
            - 'passwords.json'
            - 'cards.json'
            - 'iban.json'
            - 'tokens.json'
    condition: selection or selection_file
falsepositives:
    - Legitimate security tools or browser utilities
level: high

IOC List

Indicator Value Type
SHA-256 9d3d5ac032a3d26671c21b3b8832c46785f30523b3631ff2d59d5eaf3494d661 Hash
Export name Bootstrap PE export
Module name chrome_decrypt.dll PE export directory name
Mutex Unknown (CreateMutexW with dynamic name expected) Runtime
SQLite version 3.49.1 (source ID 873d4e274b...) Build artifact
Output files fingerprint.json, cookies.json, passwords.json, passwords_account.json, cards.json, iban.json, tokens.json Filesystem
ABE strings ASTER_KEY:, aster_app_bound_encrypted_key, NO_ABE:Browser uses legacy DPAPI Strings

Behavioral Fingerprint

This binary is a 1 MB x64 DLL with a single Bootstrap export. Upon load, it initializes COM, queries the OS version and username, enumerates browser processes, and walks Chrome/Brave/Edge profile directories. It attempts to decrypt Chrome's Local State using App-Bound Encryption (ABE) if available, falling back to legacy DPAPI. It then opens browser SQLite databases (Cookies, Login Data, Web Data) and exports cookies, passwords, saved credit cards, IBANs, and OAuth tokens to local JSON files. No network connections are made by this module; exfiltration is delegated to a separate stage.

Detection Signatures

ATT&CK Tactic Technique Evidence
Credential Access T1555.003 — Credentials from Password Stores: Browser Chrome/Brave/Edge path strings, SQLite SELECTs for cookies/passwords/cards ^[strings.txt:249-391]
Credential Access T1552.004 — Private Keys app_bound_encrypted_key, ASTER_KEY: ABE bypass ^[strings.txt:328-333]
Discovery T1082 — System Information Discovery RtlGetVersion, GetUserNameA, GetComputerNameA, fingerprint.json ^[pefile.txt:353,382,378]
Discovery T1057 — Process Discovery CreateToolhelp32Snapshot, Process32FirstW, Process32NextW ^[pefile.txt:391-396]
Defense Evasion T1622 — Debugger Evasion IsDebuggerPresent ^[pefile.txt:471]
Defense Evasion T1497.001 — Virtualization/Sandbox Evasion: Time-Based Evasion QueryPerformanceCounter, GetTickCount ^[pefile.txt:451-452]
Execution T1055 — Process Injection DLL form + Bootstrap export with PEB-walking API resolution; intended for reflective injection ^[r2:sym.chrome_decrypt.dll_Bootstrap]
Collection T1115 — Clipboard Data Browser credential extraction implies clipboard monitoring in companion stage (not observed here)
Exfiltration T1041 — Exfiltration Over C2 Channel None in this module; delegated to separate stage

References

Provenance

  • file.txt — file v5.45
  • exiftool.json — ExifTool v12.76
  • pefile.txt — pefile (Python) + custom dump script
  • strings.txt — strings -n 6 (GNU binutils)
  • floss.txt — FireEye flare-floss (failed: argument parsing error)
  • capa.txt — Mandiant capa (failed: default signature path missing)
  • binwalk.txt — Binwalk v2.3.4
  • rabin2-info.txt — radare2 v5.x
  • r2:sym.chrome_decrypt.dll_Bootstrap — radare2 decompilation (pdc)
  • dynamic-analysis.md — CAPE skipped (no Windows guest available)