typeanalysisfamilyxenoratconfidencehighcreated2026-06-06updated2026-06-06dotnetratmalware-familyc2persistencedefense-evasiondiscoverycollectionmitre-attck
SHA-256: 6133cd0b2a8a7a1ecf353ae072c1e64934bfbeb0693cb7dc59d6d55173d6e0a7

xenorat: 6133cd0b — moom825 build, LZNT1 compression, async node C2

Executive Summary PE32 .NET Framework 4.8 RAT authored by moom825 and internally named xeno rat client.exe. Heavy use of C# async/await state machines, LZNT1 compression via native NT APIs, and a parent-child "Node" C2 architecture with DDoS-capable recv loops. OpenCTI co-label dcrat is a false positive; static evidence unambiguously points to XenoRAT.

What It Is

  • File: 119 kB PE32 GUI .NET assembly, 3 sections ^[file.txt]
  • Runtime: .NET Framework v4.0.30319 / target v4.8 ^[strings.txt:5,458]
  • Timestamp: fabricated Fri Sep 10 2083 ^[pefile.txt]
  • Version info masquerade: "Windows Updater for a better version", Company Microsoft, OriginalFilename Windows Update.exe ^[exiftool.json]
  • True identity: InternalName xeno rat client.exe, namespace xeno_rat_client, developer label moom825 ^[exiftool.json] ^[strings.txt:4,201,389]
  • Unsigned, not packed, not obfuscated — standard MSBuild output ^[rabin2-info.txt]

How It Works Entry is an async Program+<Main>d__11 state machine that bootstraps a Handler instance and begins C2 lifecycle. The Handler owns a Node (primary C2 socket) and zero or more subNodes (child / proxy sockets), enabling a hub-and-spoke or chained topology ^[strings.txt:128-129,328].

Network I/O is fully async: ConnectSubSockAsync, ReceiveAsync, SendAsync, AuthenticateAsync ^[strings.txt]. Authentication implies a shared secret or token exchanged before command dispatch. Commands are typed: Type0Receive, Type1Receive, Type2Receive, plus a debug menu and info-updater ^[strings.txt:195-197].

The SocketHandler implements two receive variants: RecvAllAsync_ddos_safer and RecvAllAsync_ddos_unsafer, suggesting built-in DDoS/stress modes ^[strings.txt:305-306]. Traffic is compressed with RtlCompressBuffer / RtlDecompressBuffer in COMPRESSION_FORMAT_LZNT1 and encrypted via .NET AES + MD5 integrity checks ^[strings.txt:204,312-313] ^[capa.txt].

Plugin architecture uses CurrentDomain_AssemblyResolve to reflectively load missing assemblies at runtime — no disk touch for plugin DLLs ^[strings.txt:198-199]. A dedicated DllHandler / DllNodeHandler pair routes binary plugin payloads over the C2 stream.

Persistence is dual-path: non-admin via startup folder and admin via registry Run key, plus schtasks scheduling ^[strings.txt:264-265] ^[capa.txt]. Uninstall and self-removal routines are present (RemoveStartup, Uninstall) ^[strings.txt].

System discovery is thorough: WMI ManagementObjectSearcher for AV and hardware enumeration, GetWindowsVersion, processor count, idle time, active window caption, and machine/user name ^[strings.txt:268,366]. Console output is captured and exfiltrated via CapturingConsoleWriter ^[strings.txt:325].

Decompiled Behavior Ghidra analysis incomplete at time of writing (CIL backend queued). radare2 function list confirms the async state machine surface: 240 functions, dominated by <MoveNext> and SetStateMachine stubs for TaskAwaiter-driven coroutines ^[rabin2]. The actual logic is IL bytecode inside .text; meaningful pseudo-C requires a .NET decompiler (dnSpy/ILSpy) rather than Ghidra/r2 CIL backends.

C2 Infrastructure No hardcoded IP, domain, or port recovered from static strings. ServerIp and ServerPort fields exist in the Node class but values are runtime constants or builder-configured — not present in string artifacts ^[strings.txt:290,404]. C2 protocol is raw TCP with LZNT1 + AES framing. subServer field suggests multi-hop / proxy chaining.

Interesting Tidbits

  • Author moom825 appears raw in the string table with no obfuscation — open-source project confidence ^[strings.txt:4]
  • LZNT1 via RtlCompressBuffer is unusual; most commodity RATs use gzip or zlib. This uses the Windows kernel compression engine directly ^[strings.txt:312-313]
  • Two hardcoded SHA-256-like hashes: 1D1CC35EA6... and 630DCD2966... — likely AES key or config integrity checks ^[strings.txt:61,93]
  • GUID $310fc5be-6f5e-479c-a246-6093a39296c0 in the manifest — possibly builder-generated ^[strings.txt:456]
  • AssemblyResolve hook for plugin loading is a textbook .NET reflective loading pattern ^[strings.txt:198]
  • No ConfuserEx, no SmartAssembly, no obfuscation — the builder trusts compilation artefacts alone

How To Mess With It (Homelab Replication)

  • Toolchain: Visual Studio 2022 + .NET Framework 4.8 target
  • Build a C# WinForms/Console app with System.Net.Sockets.TcpClient, System.IO.Compression, and System.Security.Cryptography.AesManaged
  • Implement async ReceiveAsync / SendAsync wrappers with TaskAwaiter patterns
  • Add AppDomain.CurrentDomain.AssemblyResolve += ResolveHandler for in-memory DLL loading
  • Compress test payloads with RtlCompressBuffer via P/Invoke to ntdll.dll (or use System.IO.Compression.DeflateStream as a stand-in)
  • Verify: run capa on the reproducer; expect hits for communication/socket/tcp, data-manipulation/compression, data-manipulation/encryption/aes, load-code/dotnet

Deployable Signatures

YARA

rule XenoRAT_moom825
{
    meta:
        author = "PacketPursuit"
        description = "XenoRAT by moom825 — .NET RAT with LZNT1 and async node C2"
        family = "xenorat"
    strings:
        $a1 = "moom825" ascii wide nocase
        $a2 = "xeno rat client" ascii wide nocase
        $a3 = "xeno_rat_client" ascii wide
        $b1 = "RecvAllAsync_ddos_safer" ascii wide
        $b2 = "RecvAllAsync_ddos_unsafer" ascii wide
        $b3 = "COMPRESSION_FORMAT_LZNT1" ascii wide
        $b4 = "RtlCompressBuffer" ascii wide
        $b5 = "RtlDecompressBuffer" ascii wide
        $c1 = "CurrentDomain_AssemblyResolve" ascii wide
        $c2 = "DllNodeHandler" ascii wide
        $c3 = "ConnectSubSockAsync" ascii wide
    condition:
        uint16(0) == 0x5A4D and
        (any of ($a*)) and
        (2 of ($b*)) and
        (2 of ($c*))
}

Behavioral fingerprint .NET PE with mscoree IAT only, .rsrc containing large icon, async MoveNext state machines, AES+MD5 crypto classes, and P/Invoke to ntdll.dll for RtlCompressBuffer / RtlDecompressBuffer. On execution: TCP socket to ServerIp:ServerPort, AuthenticateAsync handshake, LZNT1-compressed traffic, WMI AV query, registry Run-key persistence.

IOC list

  • SHA-256: 6133cd0b2a8a7a1ecf353ae072c1e64934bfbeb0693cb7dc59d6d55173d6e0a7
  • Mutex seed string: mutex_string ^[strings.txt:223]
  • Install path field: Install_path ^[strings.txt:230]
  • Startup name field: startup_name ^[strings.txt:149]
  • Version-info masquerade: Windows Update.exe, Windows Updater for a better version

Detection Signatures From capa static:

  • T1547.001 — Registry Run Keys / Startup Folder
  • T1053.005 — Scheduled Task
  • T1047 — Windows Management Instrumentation
  • T1082 — System Information Discovery
  • T1087 — Account Discovery
  • T1033 — System Owner/User Discovery
  • T1057 — Process Discovery
  • T1012 — Query Registry
  • T1083 — File and Directory Discovery
  • T1213 — Data from Information Repositories
  • T1560.002 — Archive via Library
  • T1140 — Deobfuscate/Decode Files or Information
  • T1027 — Obfuscated Files or Information
  • T1620 — Reflective Code Loading
  • T1497.001 — VM Detection (capa low-confidence flag)

References

Provenance Static analysis only; CAPE skipped — no Windows guest available. Artifacts: file.txt, exiftool.json, pfile.txt, strings.txt, capa.txt, binwalk.txt, rabin2-info.txt, triage.json. Tools: radare2 (CIL backend limited), Ghidra (analysis incomplete). floss CLI misfired on arg parsing; no decoded strings output.