931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8funclassified-dotnet-crypter-loader: 931242f8 — AMSI-aware AES reflective loader with 2.38 MB encrypted overlay
Executive Summary
A .NET Framework 4.8 x64 console crypter/loader compiled July 2024. The binary carries only two PE sections and a zero-length IAT, yet drags a 2.38 MB encrypted payload in its file overlay. Static evidence points to AES decryption of the overlay, AMSI bypass via byte-signature patching, and reflective bridging into native code through VirtualProtect/LoadLibrary/GetProcAddress. No hardcoded C2 strings were recovered. Distributed as P.O_.exe — a purchase-order social-engineering lure. Static-only analysis (no CAPE Windows guest available).
What It Is
- SHA-256:
931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8f - Filename:
P.O_.exe^[metadata.json] - Size: 2,410,081 bytes (2.4 MB) ^[exiftool.json]
- Type: PE32+ executable (console) x86-64 Mono/.Net assembly, 2 sections ^[file.txt]
- Timestamp: 2024-07-11 19:50:04 UTC ^[pefile.txt:40]
- .NET Target: .NET Framework 4.8 (
v4.0.30319runtime,Version=4.0.0.0mscorlib) ^[strings.txt:3,233] - Compiler: csc / Roslyn (
Microsoft.CodeAnalysisnamespace present) ^[strings.txt:185] - Linker: MSVC 14.x (
MajorLinkerVersion: 0x30) ^[pefile.txt:51] - Obfuscator: None identified — no ConfuserEx
#=qmangling, no SmartAssembly, no Xenocode. Names are unobfuscated C# identifiers. - Packer: Custom — 2.38 MB post-.rsrc overlay, entropy and content unknown (no GZip/Base64 strings observed) ^[binwalk.txt]
- Signing: Unsigned ^[rabin2-info.txt:27]
- Masquerade: Word-salad VS_VERSIONINFO — CompanyName
Eparijeq, ProductNameOkoyurufaletasiz, FileDescriptionEhiruqidico Agebikujokacozixi..., OriginalFileNameIlonimuzuyegiz, InternalNameAtukewogux, copyright© 2027 Eparijeq^[exiftool.json:36-43]
How It Works
Payload Staging
The PE has only .text (code, 23.9 KB) and .rsrc (resources, 2.5 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 0x6A00 (27,136 bytes), immediately after .rsrc ends. The overlay is 2,382,945 bytes (98.9 % of file size). Its first 24 bytes are the repeating string UKWES2V322hIwBbJ1183SGJ — likely a fixed-size header, decryption IV marker, or magic. ^[strings.txt:257-259]
Decryption Chain
Static strings show an AES-managed decryption pipeline:
AesManaged^[strings.txt:30]CreateDecryptor^[strings.txt:171]CryptoStream/CryptoStreamMode^[strings.txt:40,129]MemoryStream^[strings.txt:130]ReadAllBytesFromFile^[strings.txt:51]Decrypt^[strings.txt:202]
No GZipStream, DeflateStream, or Base64 strings were recovered, distinguishing this sibling from the AES->GZip->Base64 chain observed in 07835853. ^[strings.txt]
AMSI Bypass
Explicit AMSI API references are present and unobfuscated:
AmsiInitialize^[strings.txt:108]AmsiOpenSession^[strings.txt:141]AmsiScanBuffer^[strings.txt:160]Get_AmsiOpenSession_Byte^[strings.txt:100]Get_AmsiScanBuffer_Byte^[strings.txt:101]Get_ComplementaryStrings_Byte^[strings.txt:102]Amsi_dll^[strings.txt:126]
The Get_*_Byte methods strongly suggest byte-signature harvesting of AMSI functions for in-memory patch calculation (e.g., scanning for the 0x8B/0xFF prologue patterns then overwriting with mov eax, 0; ret). This is a well-documented AMSI bypass technique. ^[strings.txt:100-102]
Native Bridging / Reflective Execution
After decryption, the payload is bridged into unmanaged code:
VirtualProtect^[strings.txt:198]LoadLibrary^[strings.txt:218]GetProcAddress^[strings.txt:192]Marshal^[strings.txt:120]IntPtr^[strings.txt:172]ModifyMemory^[strings.txt:219]PAGE_EXECUTE_READWRITE^[strings.txt:16]AllocConsole/FreeConsole^[strings.txt:52-53]
capa confirms T1620 Reflective Code Loading and T1129 Shared Modules. ^[capa.txt]
The ExecuteMethod, GetMethod, Invoke, and Assembly strings confirm the standard .NET reflective assembly loading pattern: decrypt -> Assembly.Load(byte[]) -> MethodBase.Invoke. ^[strings.txt:35,36,43,215]
Anti-Analysis
- Minimal PE structure: Only 2 sections, zero IAT, EntryPoint=0x0 (outside section boundaries). pefile warns this "cannot run under Windows 8." ^[pefile.txt:3-5,56]
- No imports: The binary resolves all APIs at runtime via
LoadLibrary/GetProcAddressor P/Invoke, leaving a minimal static footprint. ^[pefile.txt:128-130] - Console stealth:
AllocConsole+FreeConsolepair suggests a transient console for debug output or for hiding window state. ^[strings.txt:52-53]
Decompiled Behavior
Ghidra import queued; radare2 CIL decompilation of entry0 (0x00402d98) shows only a 43-byte bootstrap that instantiates 0x0600002a (a .NET type token) and returns. The real logic lives in the CIL metadata, not in the native entry thunk. ^[r2:entry0]
Notable radare2 functions include sym....ctor, method...get_Count, method...Dispose, and ~50 other CIL method stubs. The function names are heavily truncated by radare2's CIL parser. ^[r2:list_functions]
C2 Infrastructure
No C2 strings recovered. No URLs, domains, IPs, mutexes, named pipes, or registry keys observed in static strings. The inner payload's C2 is either:
- Embedded inside the encrypted overlay (not recoverable without decryption key), or
- Resolved at runtime via DGA / paste-site / Telegram API (common in .NET stealer families).
Interesting Tidbits
- Overlay header: The repeated
UKWES2V322hIwBbJ1183SGJat offset 0x6A00 is 24 bytes and appears three times in the first 64 bytes of overlay. This may be a hardcoded IV, a magic constant, or a passphrase-derived key identifier. ^[strings.txt:257-259] - Spartak Moskva: The string
SpartakMoskvaappears in#Stringsmetadata. Spartak Moscow is a Russian football club — possible author watermark, cultural reference, or coincidental variable name. ^[strings.txt:27] - Purchase-order lure: Filename
P.O_.exe("Purchase Order") fits the social-engineering pattern seen across this corpus. ^[metadata.json] - No obfuscation: Unlike sibling
07835853(ConfuserEx mangled names), this sample leaves all type/method names in plaintext. The anti-analysis comes from the minimal PE structure and encrypted overlay, not from name obfuscation. - Future-dated copyright: VS_VERSIONINFO claims
© 2027 Eparijeq— three years ahead of the PE timestamp. Common in fabricated version-info masquerade. ^[exiftool.json:43]
How To Mess With It (Homelab Replication)
Goal: Build a minimal .NET AES crypter/loader that replicates the capa fingerprint of this sample.
Toolchain:
- Visual Studio 2022 or
dotnetCLI targeting .NET Framework 4.8 cscwith/target:exe /platform:x64
Compiler/linker flags:
csc /target:exe /platform:x64 /optimize+ /debug- loader.cs
Working source snippet (simplified):
using System;
using System.IO;
using System.Security.Cryptography;
using System.Reflection;
using System.Runtime.InteropServices;
class Loader {
[DllImport("kernel32")] static extern bool VirtualProtect(IntPtr addr, uint size, uint prot, out uint old);
[DllImport("kernel32")] static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")] static extern IntPtr GetProcAddress(IntPtr h, string name);
static void Main() {
byte[] key = new byte[16]; // populate
byte[] iv = new byte[16]; // populate
byte[] payload = File.ReadAllBytes("encrypted.bin");
using (AesManaged aes = new AesManaged()) {
aes.Key = key; aes.IV = iv;
using (CryptoStream cs = new CryptoStream(
new MemoryStream(payload),
aes.CreateDecryptor(), CryptoStreamMode.Read)) {
byte[] plain = new byte[payload.Length];
cs.Read(plain, 0, plain.Length);
Assembly.Load(plain).EntryPoint.Invoke(null, null);
}
}
}
}
Verification: Run capa reproducer.exe and expect hits on:
manipulate unmanaged memory in .NETinvoke .NET assembly methodlink function at runtime on Windowscompiled to the .NET platform
What you'll learn: How a 30-line C# program produces a capa signature nearly identical to a 2.4 MB production crypter.
Deployable Signatures
YARA Rule
rule UnclassifiedDotNetCrypterLoader_AmsiAware {
meta:
description = ".NET AES crypter/loader with AMSI bypass and minimal 2-section PE"
author = "PacketPursuit"
date = "2026-07-01"
sha256 = "931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8f"
strings:
$dotnet = ".NETFramework,Version=v4.8" ascii wide
$aes1 = "AesManaged" ascii wide
$aes2 = "CreateDecryptor" ascii wide
$amsi1 = "AmsiInitialize" ascii wide
$amsi2 = "AmsiOpenSession" ascii wide
$amsi3 = "AmsiScanBuffer" ascii wide
$amsi_byte1 = "Get_AmsiOpenSession_Byte" ascii wide
$amsi_byte2 = "Get_AmsiScanBuffer_Byte" ascii wide
$native1 = "VirtualProtect" ascii wide
$native2 = "LoadLibrary" ascii wide
$native3 = "GetProcAddress" ascii wide
$overlay_magic = "UKWES2V322hIwBbJ1183SGJ" ascii wide
$readfile = "ReadAllBytesFromFile" ascii wide
$modify = "ModifyMemory" ascii wide
condition:
uint16(0) == 0x5A4D and
$dotnet and
(2 of ($aes*)) and
(2 of ($amsi*)) and
(2 of ($native*)) and
filesize > 1MB
}
Behavioral Hunt Query (Sysmon / EQL)
process where
process.pe.original_file_name in ("P.O_.exe", "*.exe") and
process.command_line == null and
(dll.name == "amsi.dll" or image_loaded.name == "amsi.dll") and
(process.Ext.memory_region.protection == "RWX" or
process.thread.Ext.call_stack_summary regex ".*VirtualProtect.*")
IOC List
| Indicator | Value | Type |
|---|---|---|
| SHA-256 | 931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8f |
Hash |
| MD5 | 03e1884cfe06fe4bac0e45dfb38b548b |
Hash |
| Filename | P.O_.exe |
Filename |
| CompanyName | Eparijeq |
VersionInfo |
| ProductName | Okoyurufaletasiz |
VersionInfo |
| InternalName | Atukewogux |
VersionInfo |
| OriginalFileName | Ilonimuzuyegiz |
VersionInfo |
| Overlay magic | UKWES2V322hIwBbJ1183SGJ |
Bytes |
| AMSI patch methods | Get_AmsiOpenSession_Byte, Get_AmsiScanBuffer_Byte |
Method names |
Behavioral Fingerprint
This binary is a .NET Framework 4.8 console assembly with a minimal 2-section PE and zero IAT. On execution, it loads amsi.dll, harvests byte signatures from AmsiOpenSession and AmsiScanBuffer, decrypts a ~2.4 MB payload from its own file overlay using AesManaged with CryptoStream, then bridges into native code via VirtualProtect/LoadLibrary/GetProcAddress and invokes the decrypted assembly through Assembly.Load -> MethodBase.Invoke. No hardcoded network indicators are present in the outer binary.
Detection Signatures
| capa Capability | ATT&CK Mapping |
|---|---|
| manipulate unmanaged memory in .NET | T1055 Process Injection |
| get process image filename | T1083 File and Directory Discovery |
| link function at runtime on Windows | T1129 Shared Modules |
| invoke .NET assembly method | T1620 Reflective Code Loading |
| unmanaged call | T1620 Reflective Code Loading |
| compiled to the .NET platform | — |
References
- Artifact ID:
08ac692b-e8a6-40d8-9b31-ab5c29594b58(OpenCTI) - MalwareBazaar: https://bazaar.abuse.ch/sample/931242f8aab64f678147e83833b39bb35111e4359824f7ab694a74d5a80b8f8f/
- Related wiki: unclassified-dotnet-crypter-loader, amsi-bypass-byte-patch, version-info-masquerade, reflective-assembly-delegate-execution, dotnet-manifest-resource-decryption
Provenance
file.txt— file(1) 5.44exiftool.json— ExifTool 12.76pefile.txt— pefile 2023.2.7strings.txt— GNU strings 2.40capa.txt— flare-capa 7.0.1 (static, dotnet)binwalk.txt— binwalk 2.3.3rabin2-info.txt— radare2 5.8.8metadata.json— OpenCTI connector output- Radare2 analysis: level 3, 155 functions, entry0 at 0x00402d98