jscript-environment-variable-staging
Overview
A defense-evasion and payload-delivery technique in which a JScript/WScript carrier encodes a binary payload (typically a PE or .NET assembly) as a series of strings, assigns each string to a unique process-scoped environment variable via WScript.Shell.Environment("Process"), and then spawns a PowerShell child process that reads the variables back and reconstructs the payload in-memory. This breaks the payload across the process environment block, making memory-dump analysis and string-based detection harder.
Observed Variants
| Variant | Payload Encoding | Staging Count | Inner Stage | Sample |
|---|---|---|---|---|
| CJK steganography | CJK characters (byte = charcode - 0x3400) |
384 env vars | PowerShell → .NET reflective load | 0de6482c |
| Hangul steganography | Hangul Syllables (byte = charcode - 0xAC00) |
347 env vars + fallback CJK stream cipher | PowerShell → .NET reflective load | 7129076f |
| CJK Unified Ideographs | CJK characters (byte = charcode - 0x4E00) |
381 env vars | XSLT JScript extension → conhost --headless powershell → .NET reflective load |
eba13078 |
Technique Details
- Encode the raw payload into a series of strings (e.g., CJK characters, Base64, hex).
- Assign each string to a process-scoped environment variable via
WScript.Shell.Environment("Process").Item(var_name) = payload_chunk. - Spawn a PowerShell process that iterates over the variable names, concatenates the chunks, decodes them, and either writes to disk or loads reflectively.
- Cleanup may include unsetting variables or self-deletion of the JScript carrier.
Detection Opportunities
- Sigma rule:
ImageLoadedcontainswscript.exewith unusually large command-line arguments, followed bypowershell.exewith-EncodedCommandor inline script reading$env:variables. - Memory forensics: scan process environment blocks for high counts of variables containing Base64, CJK characters, or long alphanumeric strings.
- EDR: flag
WScript.Shellcreating more than N environment variables in rapid succession.
References
- unclassified-js-cjk-stego-dropper — observed in sample
0de6482c - cjk-unicode-steganography — concept page for the CJK encoding primitive