typeconceptfamilyconceptconfidencehighcreated2026-07-17dotnetobfuscationloadermetadatastagingresearch-target

Raw .NET Metadata Staging

A staging technique where a .NET Framework assembly is stored inside another executable not as a complete PE file, but as raw Common Intermediate Language (CIL) bytecode and .NET metadata streams stripped of the DOS/PE header. The outer loader reconstructs or directly hosts the assembly at runtime.

How it works

A standard .NET PE contains:

  1. DOS header (MZ)
  2. PE header (PE\0\0)
  3. Section headers
  4. CLR directory entry pointing to the COR20 header
  5. Metadata root (BSJB) with streams (#~, #Strings, #US, #GUID, #Blob)
  6. CIL bytecode in .text

In raw metadata staging, only items 5 and 6 are preserved. The outer loader either:

  • Reconstructs a PE header and maps the assembly into memory for Assembly.Load
  • Uses ICLRRuntimeHost or _CorExeMain to host the raw metadata directly
  • Writes the raw bytes to a temp file and spawns a new process (observed in 0ce2a9be)

Why attackers use it

  • Evasion: Standard PE embed scanners (pefile, binwalk, sigcheck) miss the payload because there is no MZ+PE signature.
  • Size reduction: Removing the DOS stub and PE headers saves ~512 bytes per payload (minor, but adds up in multi-payload droppers).
  • Builder simplicity: The outer stub only needs to copy the raw bytes and add a header or launch them; no need to preserve a valid nested PE.

Detection

Method Technique
Static Search overlay for BSJB without a preceding MZ within 0x400 bytes
Static Entropy scan of overlay — raw CIL has lower entropy than encrypted data (~4.5–6.0)
Dynamic Monitor child processes spawned by Delphi/VB6/native droppers with .NET runtime loaded

Observed in this corpus

  • Sample 0ce2a9be — Delphi VCL native stub stores AgentTesla .NET assembly as raw metadata in overlay. No MZ+PE precedes the BSJB root. ^[/intel/analyses/0ce2a9bef251a42648a4ef198c4da7cb4c707b9635b13036d3d552fc87ac1566.html]

Related