typeanalysisfamilyremusstealerconfidencemediumcreated2026-06-17updated2026-06-17pepackerobfuscationanti-debuganti-vmevasioninfostealermalware-family
SHA-256: 2b2293a0cd9ff8648a95a9a46e6999c9e9961fc281ff5d0b698a22755974c621

remusstealer: 2b2293a0 — Protector Lab (plab) AES-GCM overlay packer, May 2026

Executive Summary

A 3.1 MB PE32+ x64 console executable packed with the commercial Protector Lab (plab) toolchain. The outer binary is a MinGW-w64 GCC 15.2.0 stub that decrypts a large AES-256-GCM payload overlay (PLABOV21 / PLABPKG2) at runtime. It carries configurable anti-debug, anti-VM, and polymorphism levels, resolving sensitive APIs dynamically via GetProcAddress. The OpenCTI label is remusstealer; no stealer-specific strings surface in the outer binary, so family attribution rests on the decrypted payload which is not recoverable statically.

What It Is

Field Value Provenance
SHA-256 2b2293a0cd9ff8648a95a9a46e6999c9e9961fc281ff5d0b698a22755974c621 ^[metadata.json]
File name QCsMTlSm0AqU.exe ^[metadata.json]
Size 3,255,533 bytes ^[file.txt]
Type PE32+ executable (console) x86-64, 19 sections ^[file.txt]
Compile stamp Fri May 15 07:42:56 2026 UTC ^[pefile.txt:34]
Linker LLD 18.1.8 (MinGW-w64) implied by toolchain strings
Compiler GNU C23 15.2.0, -O2 -fno-stack-protector -fexceptions ^[strings.txt:2585]
Signed No ^[rabin2-info.txt]
Packing Protector Lab (plab) overlay v2, AES-256-GCM encrypted ^[strings.txt:1688], ^[strings.txt:1755]

The binary is not UPX-packed. Its payload lives in a high-entropy overlay at the tail of the file (file reports overlay: true) ^[rabin2-info.txt].

How It Works

1. Overlay structure

At offset 0x31ACC0 near EOF, the footer reads PLABOV21 followed by a small header (PLABPKG2 v2 also appears elsewhere). This is the Protector Lab overlay bundle format — a encrypted blob carrying the real payload. The outer stub decrypts it with AES-256-GCM using BCrypt* APIs ^[strings.txt:1717-1735].

2. Anti-analysis suite

The protector namespace implements a multi-level guard system:

  • Anti-debug levels: none, basic, strong — configurable at build time via a JSON manifest ^[ghidra:sym.protector__anti_debug_level_to_string].
  • PEB debug indicators (peb_debug_indicators) ^[strings.txt:4569]
  • Kernel debugger present (kernel_debugger_present) ^[strings.txt:4561]
  • Hardware breakpoint check (hardware_breakpoints_set) ^[strings.txt:4565]
  • Suspicious instrumentation module scan (suspicious_instrumentation_module) with a pattern table (kPatterns) ^[strings.txt:4566-4567]
  • Remote-process anti-debug (anti_debug_check_remote) ^[strings.txt:4577]
  • Child-process monitoring (anti_debug_monitor_child) ^[strings.txt:4579]

The stub resolves NtQueryInformationProcess and NtQuerySystemInformation dynamically to avoid IAT leakage ^[strings.txt:4557-4559].

3. Polymorphism / build-time config

polymorphismLevel is a manifest token ^[strings.txt:1681], validated by validate_polymorphism_level_token ^[strings.txt:4547]. The overlay key is derived from a per-build seed (stub_deterministic_seed) ^[strings.txt:4468], meaning each build may use a different decryption key even if the payload is identical.

4. Outer stub capabilities (deduced from imports)

The stub imports only standard Windows/CRT APIs plus bcrypt.dll:

  • BCryptOpenAlgorithmProvider, BCryptGenerateSymmetricKey, BCryptEncrypt, BCryptDecrypt, BCryptGenRandom, BCryptHashData ^[rabin2-info.txt]
  • CreateProcessW, ResumeThread, GetThreadContext, SetThreadContext, VirtualAlloc, VirtualProtect, ReadProcessMemory, WriteProcessMemory ^[rabin2-info.txt]
  • IsDebuggerPresent, CheckRemoteDebuggerPresent ^[rabin2-info.txt]

This import profile is consistent with process hollowing or reflective injection: allocate memory in a child process, decrypt the payload into it, and resume execution.

Decompiled Behavior

Entry point (entry0) is the standard MinGW-w64 CRT startup (__tmainCRTStartup) ^[r2:entry0]. The real work begins in stub_execute_guard_plan_or_throw, which:

  1. Parses a JSON manifest (parse_manifest_from_json) ^[strings.txt:4550]
  2. Validates anti_debug_level and polymorphism_level tokens ^[strings.txt:4545-4548]
  3. Reads the overlay blob from the PE tail
  4. Derives an AES key (derive_inner_aes_key, derive_overlay_aes_key) ^[strings.txt:4627-4642]
  5. Decrypts and verifies the package (verify_package_and_decode_payload) ^[strings.txt:4539]
  6. Jumps to or injects the decrypted payload

Ghidra timed out on full decompilation of the 900 KB .text; radare2 pseudocode confirms the guard-plan flow above. No C2 or wallet strings are visible in the outer binary.

C2 Infrastructure

None recoverable statically. All network behavior is expected to reside inside the AES-GCM payload overlay. The outer binary has zero hardcoded IPs, domains, or URLs.

Interesting Tidbits

  • Protector Lab branding is unambiguous: plab.overlay.bundle.v1, plab.inner.pkg.v1, plab-stub log prefixes, and PLABOV21 / PLABPKG2 magic headers ^[strings.txt:146,1618,1641,1747,1755,23450].
  • No stealer-specific strings (browser names, wallets, Telegram, Discord, etc.) appear in the outer binary ^[strings.txt:grep results].
  • Large binary size (3.1 MB) is mostly the encrypted payload overlay plus heavy MinGW C++ standard-library bloat (libstdc++, libgcc, locale facet shims).
  • No CAPE detonation due to lack of a Windows guest ^[dynamic-analysis.md]; dynamic TTPs are inferred from static indicators only.

How To Mess With It (Homelab Replication)

Build a comparable MinGW-w64 console stub that embeds an encrypted payload:

  1. Toolchain: MinGW-w64 GCC 15.2.0 (ucrt), LLD 18.1.8, -O2 -fno-stack-protector
  2. Encrypt payload: Use Windows BCryptOpenAlgorithmProvider with BCRYPT_AES_ALGORITHM + BCRYPT_CHAIN_MODE_GCM, 256-bit key, 96-bit nonce, 128-bit tag.
  3. Append footer: Write PLABOV21 + 16-byte header to the tail of the PE.
  4. Stub logic: At runtime, locate the overlay via GetModuleFileNameW → read last N bytes → derive key from a build seed → decrypt → VirtualAlloc + copy + CreateThread or process-hollow.
  5. Verification: capa will fail on the outer stub (no capa signatures installed); instead, verify by checking BCrypt* imports and the PLABOV21 footer with xxd.

Deployable Signatures

YARA

rule protector_lab_overlay
{
    meta:
        description = "Protector Lab (plab) AES-GCM overlay packer footer"
        author = "titus"
        date = "2026-06-17"
        reference = "raw/analyses/2b2293a0cd9ff8648a95a9a46e6999c9e9961fc281ff5d0b698a22755974c621"
    strings:
        $plabov = "PLABOV21" ascii
        $plabpkg = "PLABPKG2" ascii
        $bundle = "plab.overlay.bundle.v1" ascii
        $inner = "plab.inner.pkg.v1" ascii
        $aes_gcm = "payloadEncoding=aes-256-gcm-v2" ascii
        $bcrypt1 = "BCryptOpenAlgorithmProvider AES" ascii wide
        $bcrypt2 = "BCryptSetProperty GCM" ascii wide
        $anti1 = "anti_debug_level_token" ascii
        $anti2 = "polymorphism_level_token" ascii
    condition:
        uint16(0) == 0x5A4D and
        ($plabov or $plabpkg) and
        2 of ($bundle, $inner, $aes_gcm) and
        1 of ($bcrypt1, $bcrypt2) and
        1 of ($anti1, $anti2)
}

Sigma

title: Protector Lab Packer Execution
description: Detects execution of binaries with Protector Lab anti-debug and overlay decryption behavior
status: experimental
logsource:
    product: windows
    category: process_creation
detection:
    selection:
        CommandLine|contains:
            - '.exe'
    selection_load:
        - ImageLoaded|contains: 'bcrypt.dll'
    selection_api:
        - CallTrace|contains:
            - 'BCryptOpenAlgorithmProvider'
            - 'BCryptDecrypt'
            - 'BCryptGenerateSymmetricKey'
        - CallTrace|contains:
            - 'IsDebuggerPresent'
            - 'CheckRemoteDebuggerPresent'
            - 'NtQueryInformationProcess'
    condition: selection and (selection_load or selection_api)
falsepositives:
    - Legitimate software using BCrypt for encryption
level: medium

IOC List

Type Value Notes
SHA-256 2b2293a0cd9ff8648a95a9a46e6999c9e9961fc281ff5d0b698a22755974c621 Outer stub
File name QCsMTlSm0AqU.exe Masquerade name
Technique protector-lab-overlay Packing / payload encryption
Magic footer PLABOV21 / PLABPKG2 Overlay bundle identifiers
Compiler GNU C23 15.2.0 MinGW-w64 Build fingerprint
Payload encoding aes-256-gcm-v2 Stated in strings

Behavioral Fingerprint

The binary is a large x64 console PE with a high-entropy tail overlay, minimal network-related imports, but heavy bcrypt.dll usage for AES-GCM operations. At startup it resolves NtQueryInformationProcess, checks debug registers and instrumentation modules, then derives an AES key from a build-time seed to decrypt the tail overlay into allocated memory before transferring control. The presence of PLABOV21 / PLABPKG2 magic headers at the end of the file is a reliable packer fingerprint.

References

  • OpenCTI artifact 295bca33-b50f-49a2-993b-f1c4673740d6 labeled remusstealer
  • MalwareBazaar / abuse.ch hash submission

Provenance

  • file.txt: file(1) output
  • pefile.txt: pefile header dump
  • rabin2-info.txt: radare2 binary info
  • strings.txt: static strings extraction
  • dynamic-analysis.md: CAPE sandbox report (skipped — no Windows guest)
  • ghidra: entry0 decompilation via radare2-MCP