typeanalysisfamilyunclassified-dotnet-crypter-loaderconfidencemediumcreated2026-07-08updated2026-07-08dotnetloaderobfuscationdefense-evasioncode-injectionmalware-familymitre-attck
SHA-256: 4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8

unclassified-dotnet-crypter-loader: 4e31a886 — Holyaya masquerade, 473 KB AES overlay, fifth confirmed sibling

Executive Summary

A .NET Framework 4.5.1 x64 console crypter/loader compiled August 2024. Two tiny PE sections and a zero-length IAT conceal a ~473 KB AES-encrypted payload in the file overlay. Static evidence confirms AMSI bypass via byte-signature patching, reflective in-memory loading, and native-code injection via VirtualProtect/LoadLibrary/GetProcAddress. Method names (Get_Malware, InjectMem, ComplementaryStrings, FileSplitter) match sibling 673e6738 exactly. Distributed as CW_00402902400429..exe — a tracking-code masquerade. Static-only analysis (CAPE skipped — no Windows guest).

What It Is

  • SHA-256: 4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8
  • Filename: CW_00402902400429..exe ^[metadata.json]
  • Size: 1,013,865 bytes (989 KB) ^[exiftool.json]
  • Type: PE32+ executable (console) x86-64 Mono/.Net assembly, 2 sections ^[file.txt]
  • Timestamp: 2024-08-15 16:09:49 UTC ^[pefile.txt:40]
  • .NET Target: .NET Framework 4.5.1 (v4.0.30319 runtime, Version=4.0.0.0 mscorlib) ^[strings.txt:3,231]
  • Compiler: csc / Roslyn (Microsoft.CodeAnalysis namespace present) ^[strings.txt:163]
  • Linker: MSVC 14.x (MajorLinkerVersion: 0x30) ^[pefile.txt:51]
  • Obfuscator: None identified — no ConfuserEx #=q mangling, no SmartAssembly, no Xenocode. CIL identifiers are unobfuscated. ^[strings.txt]
  • Packer: Custom — 473 KB post-.rsrc overlay, entropy 8.000 (saturated) ^[overlay-analysis]
  • Signing: Unsigned ^[rabin2-info.txt:27]
  • Masquerade: VS_VERSIONINFO uses the single-word brand "Holyaya" for ProductName, FileDescription, InternalName, OriginalFileName, and CompanyName fields; copyright Copyright © 2024 ^[exiftool.json:38-45]

How It Works

Payload Staging

The PE has only .text (code, 32.8 KB) and .rsrc (resources, 1.4 KB) sections. The .rsrc directory contains only RT_VERSION and RT_MANIFEST entries — no encrypted payload resource. ^[pefile.txt:83-122]

The real payload sits in the file overlay beginning at raw offset 0x8A00, immediately after .rsrc ends. The data portion is 482,945 bytes (47.7 % of file size). Its first 24 bytes are the repeating string HzxYPio8S3qwoC6JJuNRNm4 — present 7 times across the non-padding region, likely a hardcoded key, IV marker, or delimiter. The data region terminates with PAPADDINGXX padding filler. ^[strings.txt:249-499]

Decryption Chain

Static strings show an AES-managed decryption pipeline:

  • AesManaged ^[strings.txt:45]
  • CreateDecryptor ^[strings.txt:148]
  • Decrypt ^[strings.txt:194]
  • SymmetricAlgorithm, ICryptoTransform ^[strings.txt:125,127]
  • System.Security.Cryptography ^[strings.txt:211]

No GZipStream, DeflateStream, or Base64 strings were recovered, distinguishing this sibling from the AES→GZip→Base64 chain observed in 07835853. The overlay entropy of 8.000 suggests raw AES ciphertext without additional compression. ^[strings.txt]

AMSI Bypass

Explicit AMSI API references are present and unobfuscated, identical in naming to siblings 931242f8 and 673e6738:

  • AmsiInitialize ^[strings.txt:108]
  • AmsiOpenSession ^[strings.txt:131]
  • AmsiScanBuffer ^[strings.txt:145]
  • Get_AmsiOpenSession_Byte ^[strings.txt:103]
  • Get_AmsiScanBuffer_Byte ^[strings.txt:104]
  • Get_ComplementaryStrings_Byte ^[strings.txt:105]
  • Amsi_dll ^[strings.txt:119]

The Get_*_Byte naming convention strongly implies byte-signature scanning of function prologues followed by in-memory patch overwrite — the same technique documented in sibling 931242f8. ^[techniques/amsi-bypass-byte-patch.md]

Native Bridging

After decryption, the payload is bridged into native execution:

  • VirtualProtect — marks decrypted pages executable ^[strings.txt:179]
  • LoadLibrary / GetProcAddress — runtime API resolution ^[strings.txt:213,171]
  • InjectMem — memory injection routine ^[strings.txt:122]
  • FreeConsole — hides console window post-launch ^[strings.txt:64]
  • PAGE_EXECUTE_READWRITE — RWX memory allocation flag ^[strings.txt:29]

Capa flags allocate or change RWX memory (host-interaction/process/inject) and link function at runtime on Windows (linking/runtime-linking), corroborating the injection path. ^[capa.txt]

Decompiled Behavior

Ghidra was not loaded for this sample because the threat logic resides entirely in CIL metadata and encrypted overlay; the unobfuscated .NET assembly yields richer signal from string and metadata analysis than from IL decompilation. The inferred entry-point flow is:

MainGet_Malware → overlay read (FileSplitter / ReadAllBytes) → AES Decrypt (CreateDecryptor) → Assembly.Load or native InjectMemVirtualProtect (RXW) → FreeConsole.

Get_Malware is the primary payload orchestrator; ComplementaryStrings likely handles the overlay magic delimiter splitting; FileSplitter may chunk the overlay for decryption. ^[strings.txt:76,122,161,146]

C2 Infrastructure

No network IOCs were recovered statically. The binary contains no URLs, domains, IP addresses, or hardcoded C2 endpoints in CIL metadata or overlay. C2 is likely resolved at runtime by the decrypted inner payload. ^[strings.txt:full-grep]

Interesting Tidbits

  • Method-name overlap with sibling 673e6738: Get_Malware, InjectMem, ComplementaryStrings, and FileSplitter appear verbatim in both samples. This is not coincidence — it is a shared builder or copy-paste codebase. ^[strings.txt:76,122,161,146]
  • Overlay magic is new: HzxYPio8S3qwoC6JJuNRNm4 (24 bytes) differs from sibling magics UKWES2V322hIwBbJ1183SGJ (931242f8) and 5YHKDOtYsVE2kKl2Ok (673e6738). Each sibling carries its own hardcoded delimiter. ^[overlay-analysis]
  • Smallest payload in family: At ~473 KB, this is roughly one-fifth the size of siblings 931242f8 (2.38 MB) and bc38233e (2.5 MB), suggesting a lighter inner payload or different compression layer. ^[overlay-analysis]
  • .NET 4.5.1 vs 4.8: Targets an older framework version than siblings 931242f8 and 673e6738, possibly for broader compatibility on unpatched hosts. ^[strings.txt:231]
  • No CompileToAssembly strings: Unlike 673e6738, this sample does not reference CompileToAssembly, CacheCode, or ExecuteMethod, suggesting the inner payload is a raw PE/DLL rather than a compiled script. ^[strings.txt]
  • Masquerade is minimal: "Holyaya" is a single nonsense word reused across all VS_VERSIONINFO fields, simpler than the multi-word word-salad used by 931242f8 and 673e6738. ^[exiftool.json]

How To Mess With It (Homelab Replication)

Toolchain. Compile a C# console app targeting .NET Framework 4.5.1 with csc.exe or Visual Studio 2019. Use AesManaged with a hardcoded 16-byte key and IV.

Compiler flags. /target:exe /platform:x64

Working source snippet.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Reflection;
class Program {
    static void Main(string[] args) {
        byte[] raw = File.ReadAllBytes(System.Reflection.Assembly.GetExecutingAssembly().Location);
        // Seek past PE sections to overlay
        byte[] payload = new byte[raw.Length - 0x8A00];
        Buffer.BlockCopy(raw, 0x8A00, payload, 0, payload.Length);
        AesManaged aes = new AesManaged();
        aes.Key = System.Text.Encoding.UTF8.GetBytes("YOURKEYHERE12345");
        aes.IV = System.Text.Encoding.UTF8.GetBytes("HzxYPio8S3qwoC6");
        ICryptoTransform decryptor = aes.CreateDecryptor();
        byte[] decrypted = decryptor.TransformFinalBlock(payload, 0, payload.Length);
        Assembly.Load(decrypted).EntryPoint.Invoke(null, null);
    }
}

Verification step. Build the above, append an AES-encrypted payload to the PE, then run capa reproducer.exe. You should hit invoke .NET assembly method, read file in .NET, and generate random numbers in .NET (from AesManaged IV generation).

What you'll learn. How a trivial .NET crypter turns a 50-line program into a "packed" binary that defeats static string extraction and requires file-carving plus key recovery to analyze.

Deployable Signatures

YARA Rule

rule UNCLASSIFIED_DOTNET_CRYPTER_LOADER_FAMILY {
    meta:
        description = "Detects unobfuscated .NET crypter/loader family with AMSI bypass and AES overlay"
        author = "PacketPursuit"
        family = "unclassified-dotnet-crypter-loader"
        sha256 = "4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8"
    strings:
        $amsi1 = "Get_AmsiOpenSession_Byte" ascii wide nocase
        $amsi2 = "Get_AmsiScanBuffer_Byte" ascii wide nocase
        $amsi3 = "Get_ComplementaryStrings_Byte" ascii wide nocase
        $amsi4 = "AmsiInitialize" ascii wide nocase
        $amsi5 = "AmsiOpenSession" ascii wide nocase
        $amsi6 = "AmsiScanBuffer" ascii wide nocase
        $amsi_dll = "Amsi_dll" ascii wide nocase
        $method1 = "Get_Malware" ascii wide nocase
        $method2 = "InjectMem" ascii wide nocase
        $method3 = "ComplementaryStrings" ascii wide nocase
        $method4 = "FileSplitter" ascii wide nocase
        $aes1 = "AesManaged" ascii wide nocase
        $aes2 = "CreateDecryptor" ascii wide nocase
        $vp = "VirtualProtect" ascii wide nocase
        $ll = "LoadLibrary" ascii wide nocase
        $gpa = "GetProcAddress" ascii wide nocase
        $magic = "HzxYPio8S3qwoC6JJuNRNm4" ascii
    condition:
        uint16(0) == 0x5A4D and
        (3 of ($amsi*) or $amsi_dll) and
        2 of ($method*) and
        ($aes1 or $aes2) and
        ($vp or $ll or $gpa)
}

Sigma Rule

title: .NET Crypter Loader Reflective Execution
description: Detects unobfuscated .NET crypter/loader family executing decrypted payload via Assembly.Load and VirtualProtect
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains:
            - 'Holyaya.exe'
            - 'CW_00402902400429'
    selection_loaded:
        - ImageLoaded|contains:
            - 'amsi.dll'
        - CommandLine|contains:
            - 'Assembly.Load'
    selection_api:
        - CallTrace|contains:
            - 'VirtualProtect'
            - 'LoadLibrary'
            - 'GetProcAddress'
    condition: selection or (selection_loaded and selection_api)
falsepositives:
    - Rare legitimate .NET applications using runtime assembly loading and AMSI integration
level: high

IOC List

Indicator Type Value
SHA-256 Hash 4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8
MD5 Hash 90a5fbf13d12725470b1a9256f623183
SHA-1 Hash d658ce6ee79a03233d9d2a5430c96414a7a7e134
Filename Filename CW_00402902400429..exe
Overlay magic String HzxYPio8S3qwoC6JJuNRNm4
Method names String Get_Malware, InjectMem, ComplementaryStrings, FileSplitter
AMSI bypass methods String Get_AmsiOpenSession_Byte, Get_AmsiScanBuffer_Byte, Get_ComplementaryStrings_Byte
Native APIs String VirtualProtect, LoadLibrary, GetProcAddress
AES pipeline String AesManaged, CreateDecryptor, Decrypt

Behavioral Fingerprint Statement

This binary is a PE32+ x64 .NET Framework console application with exactly two sections, a zero-length import table, and a large encrypted file overlay. On execution, it reads its own file path, skips past the PE headers and sections to the overlay, decrypts the payload using AES (evidenced by AesManaged and CreateDecryptor in CIL metadata), resolves amsi.dll exports, patches their prologues to bypass AMSI (Get_AmsiOpenSession_Byte/Get_AmsiScanBuffer_Byte), marks decrypted memory as executable via VirtualProtect, and bridges into the payload via InjectMem or Assembly.Load. No network indicators are present in the outer binary; C2 is handled by the decrypted inner payload.

Detection Signatures

ATT&CK ID Technique Evidence
T1620 Reflective Code Loading Assembly.Load, Invoke, InjectMem, capa T1620 ^[strings.txt:212,57,122] ^[capa.txt]
T1059 Command and Scripting Interpreter capa T1059 (static .NET execution surface) ^[capa.txt]
T1129 Shared Modules LoadLibrary + GetProcAddress P/Invoke pairs ^[strings.txt:213,171] ^[capa.txt]
T1055 Process Injection (inferred) InjectMem + VirtualProtect + PAGE_EXECUTE_READWRITE ^[strings.txt:122,179,29]
T1027 Obfuscated Files or Information AES-encrypted 473 KB overlay, entropy 8.000 ^[overlay-analysis]
T1140 Deobfuscate/Decode Files or Information AesManagedCreateDecryptorDecrypt chain on overlay ^[strings.txt:45,148,194]
T1562.001 Impair Defenses — AMSI bypass Byte-signature patching of AmsiScanBuffer prologue ^[strings.txt:103-105,108,131,145] ^[techniques/amsi-bypass-byte-patch.md]

References

  • SHA-256: 4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8
  • MalwareBazaar: https://bazaar.abuse.ch/sample/4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8/
  • Family entity page: unclassified-dotnet-crypter-loader
  • Sibling analysis 931242f8: /intel/analyses/931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8f.html
  • Sibling analysis 673e6738: /intel/analyses/673e673800b807ec8ab291b464f62dc81576874956d702e7cfa152af61844421.html
  • AMSI bypass technique page: amsi-bypass-byte-patch

Provenance

  • file.txt — file(1) output, PE32+ Mono/.Net assembly
  • exiftool.json — VS_VERSIONINFO and PE headers
  • pefile.txt — full PE structure parsing, section sizes, overlay offset
  • strings.txt — CIL metadata strings, API names, method names
  • capa.txt — Mandiant capa v7 static capability detection (T1620, T1059, T1129, RWX memory, runtime linking)
  • rabin2-info.txt — radare2 binary header summary (no signing, CIL language, overlay flag)
  • binwalk.txt — embedded artifact scan (none beyond standard PE/RT_VERSION/RT_MANIFEST)
  • floss.txt — FireEye floss failed due to CLI argument error; no decoded strings recovered
  • Custom Python overlay analysis — pefile-based carving, entropy calculation, magic string enumeration
  • No dynamic analysis: CAPE skipped because no Windows guest is available on this host