2b2293a0cd9ff8648a95a9a46e6999c9e9961fc281ff5d0b698a22755974c621remusstealer: 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:
- Parses a JSON manifest (
parse_manifest_from_json) ^[strings.txt:4550] - Validates
anti_debug_levelandpolymorphism_leveltokens ^[strings.txt:4545-4548] - Reads the overlay blob from the PE tail
- Derives an AES key (
derive_inner_aes_key,derive_overlay_aes_key) ^[strings.txt:4627-4642] - Decrypts and verifies the package (
verify_package_and_decode_payload) ^[strings.txt:4539] - 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-stublog prefixes, andPLABOV21/PLABPKG2magic 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:
- Toolchain: MinGW-w64 GCC 15.2.0 (ucrt), LLD 18.1.8,
-O2 -fno-stack-protector - Encrypt payload: Use Windows
BCryptOpenAlgorithmProviderwithBCRYPT_AES_ALGORITHM+BCRYPT_CHAIN_MODE_GCM, 256-bit key, 96-bit nonce, 128-bit tag. - Append footer: Write
PLABOV21+ 16-byte header to the tail of the PE. - Stub logic: At runtime, locate the overlay via
GetModuleFileNameW→ read last N bytes → derive key from a build seed → decrypt →VirtualAlloc+ copy +CreateThreador process-hollow. - Verification:
capawill fail on the outer stub (no capa signatures installed); instead, verify by checkingBCrypt*imports and thePLABOV21footer withxxd.
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-f1c4673740d6labeledremusstealer - MalwareBazaar / abuse.ch hash submission
Provenance
file.txt: file(1) outputpefile.txt: pefile header dumprabin2-info.txt: radare2 binary infostrings.txt: static strings extractiondynamic-analysis.md: CAPE sandbox report (skipped — no Windows guest)ghidra:entry0decompilation via radare2-MCP