4e31a886cd81ca02100d96b6b1475085dbe02d7c6f3fc72604be3ae64a56d1e8unclassified-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.30319runtime,Version=4.0.0.0mscorlib) ^[strings.txt:3,231] - Compiler: csc / Roslyn (
Microsoft.CodeAnalysisnamespace present) ^[strings.txt:163] - Linker: MSVC 14.x (
MajorLinkerVersion: 0x30) ^[pefile.txt:51] - Obfuscator: None identified — no ConfuserEx
#=qmangling, 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:
Main → Get_Malware → overlay read (FileSplitter / ReadAllBytes) → AES Decrypt (CreateDecryptor) → Assembly.Load or native InjectMem → VirtualProtect (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, andFileSplitterappear 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 magicsUKWES2V322hIwBbJ1183SGJ(931242f8) and5YHKDOtYsVE2kKl2Ok(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) andbc38233e(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
931242f8and673e6738, possibly for broader compatibility on unpatched hosts. ^[strings.txt:231] - No
CompileToAssemblystrings: Unlike673e6738, this sample does not referenceCompileToAssembly,CacheCode, orExecuteMethod, 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
931242f8and673e6738. ^[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 | AesManaged → CreateDecryptor → Decrypt 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 assemblyexiftool.json— VS_VERSIONINFO and PE headerspefile.txt— full PE structure parsing, section sizes, overlay offsetstrings.txt— CIL metadata strings, API names, method namescapa.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