JavaScript Multi-Stage Loader Malware Analysis (In Progess) 

Summary

Sample Name: Renamed to Haku.js for tracking purposes during analysis. Original filename was a SHA256 hash.

File Name: PURCHASE ORDER.js

Hashes

MD5

480282aebe33ff8a8deabab6031bb0b2

SHA1

ec88b4537ffea40d8f2363900b4ac265245aef9c

SHA256

013e0807afdbbe14fe30a302620f31147fc03caa771ff9bd7951347acdb5ecb0

Executive Summary

The analyzed sample is a heavily obfuscated multi-stage malware loader that transitions through JavaScript, PowerShell, and .NET execution layers before ultimately loading and executing a secondary .NET assembly entirely in memory.

Initial execution begins with an obfuscated JavaScript file that reconstructs hundreds of fragmented payload components and stores them as environment variables. These fragments are subsequently referenced by a PowerShell stage, concatenated into a large encoded blob, decoded through a custom alphabet-based routine, and reconstructed into a .NET assembly.

The recovered .NET assembly acts as a second-stage loader that employs reflection, runtime delegate generation, dynamic IL emission, and in-memory assembly execution techniques to avoid straightforward static analysis and detection.

Current findings indicate that no secondary payload is written to disk. Instead, the malware decrypts and executes its final stage directly from memory.


Attack Chain Overview

JavaScript Stage

Environment Variable Fragment Storage

PowerShell Reconstruction Stage

Custom Alphabet Decoder

.NET Loader Assembly

Embedded Encrypted Payload

Reflection-Based Assembly Loading

Dynamic Delegate Generation

In-Memory Payload Execution


Stage 1 – JavaScript Loader

The initial JavaScript sample contains hundreds of encoded fragments stored within a large object structure.

Analysis identified:

  • 710 individual payload fragments

  • Fragment identifiers generated using randomized variable names

  • Data stored in an object referred to internally as v728

  • Fragment reconstruction performed through environment variable assignment

Example:

v728["v1"] = [
    "zFZrReDjoO",
    "<encoded fragment>"
];

The JavaScript stage itself does not contain the final payload. Instead, it serves as a reconstruction mechanism for a larger encoded data stream.

Notable Characteristics

  • Heavy string obfuscation

  • Randomized variable names

  • Fragmented payload storage

  • Environment variable abuse for staging


Stage 2 – PowerShell Reconstruction

The PowerShell stage reconstructs the payload by concatenating 710 environment variables in a specific order.

Example behavior:

$aeXOgA = (
    $env:zFZrReDjoO +
    $env:TqPoz5PmiZyYD +
    ...
)

Analysis recovered:

  • Custom decoding alphabet:

2VKbveZNijyHk36c
  • 710 referenced environment variables

  • Reconstructed encoded payload size:

714,752 bytes

The resulting blob is decoded using a custom nibble-based encoding scheme.


Stage 3 – .NET Loader Recovery

Using the recovered alphabet and fragment ordering, the encoded blob was successfully decoded into a Windows PE file.

Recovered artifact:

payload.bin

File identification:

PE32+ executable (GUI) x86-64 Mono/.NET assembly

Assembly metadata:

Assembly Name: v1142
Runtime: .NET Framework v4.0.30319

The assembly is heavily obfuscated and uses randomized type and method names throughout.


Loader Characteristics

The recovered .NET assembly demonstrates multiple anti-analysis and stealth techniques.

Observed behaviors include:

Obfuscated Control Flow

The majority of functions contain excessive arithmetic and logical operations designed to obscure actual execution flow.

Examples include:

  • XOR chains

  • Arithmetic junk operations

  • Artificial branching

  • Dead code insertion


Runtime Reflection

The loader dynamically discovers required methods at runtime instead of statically referencing them.

Observed APIs:

GetType()
GetMethods()
GetProperties()
CreateDelegate()

This prevents many signatures from identifying the intended execution path.


Dynamic IL Generation

The malware generates executable methods at runtime using:

System.Reflection.Emit.DynamicMethod
System.Reflection.Emit.ILGenerator

Observed operations:

Emit(OpCodes.Ldarg_0)
Emit(OpCodes.Call)
Emit(OpCodes.Ret)

This technique allows execution logic to be created dynamically rather than existing in static code.


Embedded Payload Storage

The loader contains a large embedded byte array:

v2178

References to this array occur throughout the execution path.

Observed workflow:

  1. Clone embedded blob

  2. Process embedded data

  3. Generate runtime delegates

  4. Load secondary assembly

  5. Execute payload

Field analysis identified a large embedded structure:

__StaticArrayInitTypeSize = 284160

This likely contains encrypted payload material used during later stages.


In-Memory Assembly Loading

Analysis of the primary execution routine confirmed the loader dynamically resolves the .NET assembly loading mechanism through reflection.

Observed execution path:

Assembly.Load(byte[])

However, the call is not directly visible.

Instead, the malware:

  1. Locates the method through reflection

  2. Generates a DynamicMethod wrapper

  3. Creates a runtime delegate

  4. Invokes the delegate using decrypted bytes

Equivalent behavior:

Assembly.Load(decryptedPayload)

The loaded assembly is never written to disk.


Runtime Execution Logic

After loading the secondary assembly, the malware:

  1. Enumerates assembly properties

  2. Searches for a hidden property name

  3. Extracts a MethodInfo object

  4. Determines parameter count

  5. Builds an execution delegate

  6. Invokes the target method

Observed execution paths:

Action()

or

Action<string[]>

depending on the discovered method signature.

This approach bypasses direct use of:

MethodInfo.Invoke()

and instead executes through dynamically generated delegates.


Anti-Analysis Techniques

Observed techniques include:

  • Multi-stage payload reconstruction

  • Environment variable staging

  • Custom alphabet encoding

  • Obfuscated .NET metadata

  • Reflection-based API resolution

  • Dynamic IL generation

  • Runtime delegate creation

  • In-memory assembly execution

  • Hidden method discovery

  • Extensive control-flow obfuscation


Current Assessment

At this stage, the sample can be confidently classified as a multi-stage fileless .NET loader.

The loader reconstructs a hidden payload through JavaScript and PowerShell stages before ultimately executing a decrypted .NET assembly directly from memory.

No evidence has currently been identified indicating disk-based payload deployment. All recovered execution paths point toward memory-only assembly loading and execution.

Further analysis is ongoing to recover:

  • Embedded payload contents

  • Decryption routine details

  • Hidden property names

  • Final stage functionality

  • Command and control mechanisms

  • Data theft or persistence capabilities


Current Verdict

Classification:

Multi-Stage Fileless .NET Loader

Confidence:

High

Capabilities Confirmed:

  • Payload reconstruction

  • Custom decoding

  • Reflection abuse

  • Dynamic method generation

  • In-memory assembly execution

Capabilities Under Investigation:

  • Credential theft

  • Information theft

  • Persistence

  • Command and control communications

  • Additional payload delivery

Updated Assessment 

Analysis confirms the loader derives an RC4 encryption key from static seed material stored within v181. During initialization, the seed is cloned, transformed via XOR using static value v598 (0x07), and hashed using SHA256 to produce a 32-byte RC4 key. This key is subsequently used to decrypt multiple embedded byte arrays at runtime.

Static recovery of the RC4 key allowed successful decryption of several protected resources. Recovered plaintext values include System.Reflection.Assembly, Load, and EntryPoint, which are dynamically resolved and used during execution. Additional recovered strings include ntdll.dll, kernel32.dll, and LdrLoadDll, demonstrating the presence of both native API resolution and managed reflection-based execution mechanisms.

Analysis of the execution chain shows the loader decrypts reflection identifiers at runtime and uses them to invoke Assembly.Load() on an embedded .NET payload loaded directly from memory. The resulting assembly’s EntryPoint property is then resolved and executed, enabling fileless payload execution without exposing critical type, method, or property names within the static binary. This architecture combines native API resolution, RC4-protected string obfuscation, and reflection-based assembly loading to conceal execution flow and hinder static analysis.

New Findings: 

RC4 Key (SHA256 Derived)

0bd824301ad8f9c3e31312d157b7ae14
836ddb6d69775d29f96e18f7e87febc5

Recovered Runtime Strings

ntdll.dll
kernel32.dll
LdrLoadDll