typeanalysisfamilyvalleyratconfidencelowmalware-familyratdotnetpec2persistencediscovery
SHA-256: fbc07658954f87579d615e72f76335f6fae5cec34a283535a37f72d6a4abce15

valleyrat: fbc07658 — .NET Native AOT 10 MB console RAT, 52pojie build provenance

Executive Summary

A 10 MB PE32+ x64 console binary compiled with .NET Native AOT (PublishAOT) from a net10.0 project named Update, built on a workstation affiliated with the Chinese reverse-engineering forum 52pojie. The binary carries the OpenCTI label valleyrat but shares no build artefacts with the established SilverFox/ValleyRAT cluster (no LZSS, no process hollowing, no XOR-thunk dispatch). It imports the full .NET networking and cryptography stack (System.Net.Http, System.Security.Cryptography, bcrypt, crypt32) plus registry and Win32 process APIs. No C2 strings or persistence mechanisms recovered statically. Confidence in family attribution is low — treat as a distinct build variant at minimum.

What It Is

Attribute Detail
SHA-256 fbc07658954f87579d615e72f76335f6fae5cec34a283535a37f72d6a4abce15
File name MSIED8F.exe
File type PE32+ executable (console) x86-64, 6 sections ^[file.txt]
Size 10 083 840 bytes ^[triage.json]
Compiler .NET Native AOT (ILC) via MSVC 14.51 linker ^[rabin2-info.txt:11] ^[exiftool.json:18]
PDB path C:\Users\52pojie\Desktop\420\bin\Debug\net10.0\win-x64\native\Update.pdb ^[rabin2-info.txt:13]
VersionInfo CompanyName="Update", FileDescription="Update", InternalName="Update.dll" ^[exiftool.json:36-42]
Signed No ^[rabin2-info.txt:27]
Entropy .text=6.05, .rdata=6.52 ^[pefile.txt:92,112]
Exports 39 — Brotli encoder/decoder APIs + DotNetRuntimeDebugHeader ^[pefile.txt:318-358]

The PDB path reveals two things: the developer account 52pojie (吾爱破解, a well-known Chinese reverse-engineering and software-cracking community), and the project name Update compiled for net10.0 with Native AOT publishing. This is not a conventional .NET assembly — there is no COM_DESCRIPTOR directory, no CLR header, and no IL metadata. The entire runtime is compiled ahead-of-time into native x64 code, making this a self-contained single-file deployment.

How It Works

The binary is a statically-linked Native AOT executable embedding the .NET base class library, runtime, and user code into one PE. Strings show the presence of:

  • Networking: System.Net.Http, System.Net.Sockets, System.Net.WebClient, System.Net.Security, WinHttp+ ^[strings.txt:2217-2226]
  • Cryptography: System.Security.Cryptography, BCrypt, Crypt32, CryptProtectMemory, CryptUnprotectMemory ^[strings.txt:2224,2382,2383] ^[pefile.txt:369-435]
  • Registry: Microsoft.Win32.Registry, RegistryKey, RegOpenKeyExW, RegQueryValueExW ^[strings.txt:2205,2388] ^[pefile.txt:369-382]
  • Process / System: CreateProcessW, VirtualAlloc, VirtualProtect, SuspendThread, ResumeThread, NtAllocateVirtualMemory (implied via .NET runtime P/Invoke thunks) ^[pefile.txt:458-500]
  • Async I/O: Massive async/await state machine names (<SendAsync>d__, <ConnectAsync>d__, <HandleResponse>d__) ^[strings.txt:3510-3514]

The export table is dominated by Brotli compression APIs (encoder + decoder), suggesting the payload may use Brotli for compressing C2 traffic, staging data, or obfuscating embedded content. ^[pefile.txt:318-358] The DotNetRuntimeDebugHeader export is a standard Native AOT artefact for diagnostics.

No hardcoded C2 IP addresses, domains, ports, mutex names, or file paths were recovered from strings. The C2 configuration is either runtime-generated, encrypted, or pulled from an external source. ^[strings.txt — no IP:port or domain hits]

Decompiled Behavior

Ghidra import was queued but background analysis did not complete within the session window. Radare2 analysis timed out on this 10 MB binary. Consequently, decompiled pseudo-C observations are unavailable. The assessment above relies on static strings, import tables, and PE metadata. This is explicitly noted as a limitation.

C2 Infrastructure

None recovered statically. No IP addresses, domains, URLs, or ports present in strings. No mutex or named-pipe identifiers. Given the System.Net.Http and socket infrastructure embedded in the binary, C2 is almost certainly runtime-resolved (e.g., fetched from a remote config, decoded from an encrypted blob, or passed as a command-line argument).

Interesting Tidbits

  • 52pojie provenance: The PDB path C:\Users\52pojie\Desktop\420\... ties the build environment to a known Chinese cracking forum. This is either the actual developer's username or a deliberate misdirection. ^[rabin2-info.txt:13]
  • VersionInfo genericity: "Update" / "Update.dll" is the most generic possible masquerade. The binary presents as a system update helper. ^[exiftool.json]
  • Brotli exports: 37 Brotli functions exported from the PE. This is unusual for malware — likely inherited from a NuGet package (e.g., System.IO.Compression.Brotli) compiled into the Native AOT image. Whether Brotli is used for C2 compression or just dead code from the runtime is undetermined. ^[pefile.txt:318-358]
  • HTML word-list noise: Strings contain massive English word lists and HTML fragments (e.g., firstvideolightworldmediawhitecloseblackright...) starting around offset 0x7A9CEC. These appear to be noise or embedded web-scraping data, not executable strings. ^[strings.txt:11533]
  • No packing, no obfuscation: Entropy across all sections is well below 7.0. No UPX, Themida, or custom packer detected. The threat actor relies on the opacity of Native AOT compilation rather than traditional packing. ^[binwalk.txt] ^[pefile.txt:92,112,132]

How To Mess With It (Homelab Replication)

Toolchain: .NET SDK 10.0 preview or nightly with PublishAOT enabled.

Steps:

  1. Create a new console project: dotnet new console -n Update
  2. Add System.Net.Http, System.Net.Sockets, and Microsoft.Win32.Registry package references (included by default in most SDKs).
  3. In the .csproj, add:
    <PublishAot>true</PublishAot>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    
  4. Implement a simple async HTTP client loop with registry reads.
  5. Publish: dotnet publish -c Release -r win-x64 --self-contained
  6. Compare output size (expect 8–12 MB for a minimal Native AOT console app with HTTP support).

Verification: Run strings on your reproducer and compare the BCL DLL names and async state machine mangling to this sample's strings.txt. The pattern of <>c__DisplayClass and d__ async names should match.

Deployable Signatures

YARA rule

rule ValleyRAT_NativeAOT_Update_52pojie {
    meta:
        description = "Detects .NET Native AOT PEs with 52pojie build provenance and Update masquerade"
        author = "PacketPursuit"
        date = "2026-06-14"
        hash = "fbc07658954f87579d615e72f76335f6fae5cec34a283535a37f72d6a4abce15"
    strings:
        $pdb_52pojie = "Users\\52pojie\\" ascii wide
        $pdb_update = "\\native\\Update.pdb" ascii wide
        $aot1 = "DotNetRuntimeDebugHeader" ascii
        $aot2 = "System.Net.Http.dll" ascii wide
        $aot3 = "System.Security.Cryptography.dll" ascii wide
        $bro1 = "BrotliDecoderCreateInstance" ascii
        $bro2 = "BrotliEncoderCompress" ascii
    condition:
        uint16(0) == 0x5A4D and
        ($pdb_52pojie or $pdb_update) and
        $aot1 and
        2 of ($aot2, $aot3, $bro1, $bro2)
}

Behavioral fingerprint

This binary is a 10 MB PE32+ x64 console executable with no COM_DESCRIPTOR (not a conventional .NET assembly). It exports Brotli compression APIs and a DotNetRuntimeDebugHeader. At runtime it imports WinHTTP, socket, bcrypt, crypt32, and registry APIs. It does not exhibit packing or section encryption. No C2 strings are present statically. The async networking state machine names in strings indicate a modern .NET async/await C2 loop.

IOC list

Indicator Value Type
SHA-256 fbc07658954f87579d615e72f76335f6fae5cec34a283535a37f72d6a4abce15 Hash
File name MSIED8F.exe Filename
PDB path C:\Users\52pojie\Desktop\420\bin\Debug\net10.0\win-x64\native\Update.pdb Build artefact
VersionInfo Update / Update.dll / 1.0.0.0 Masquerade
Compile time 2026-04-30 04:53:24 UTC Timestamp

Detection Signatures

  • capa: Failed — signatures not installed (OSError). ^[capa.txt]
  • floss: Failed — CLI argument parsing error. ^[floss.txt]
  • YARA: PE_File_Generic, Suspicious_Crypto_Imports — generic hits only. ^[yara.txt]

References

  • silverfox — established cluster co-labeled valleyrat; this sample diverges in build stack
  • valleyrat — family entity page (stub)
  • dotnet-native-aot-rat-compilation — technique page for Native AOT malware build pattern
  • OpenCTI label: valleyrat (preliminary, unverified for this build variant)

Provenance

  • file.txt, exiftool.json, pefile.txt, rabin2-info.txt — file type, metadata, PE structure
  • strings.txt — static string extraction (13445 lines)
  • triage.json — OpenCTI labels and family ascription
  • binwalk.txt — no packing detected
  • yara.txt — generic YARA hits only
  • capa.txt — failure; signatures missing
  • floss.txt — failure; bad CLI invocation
  • dynamic-analysis.md — CAPE skipped; no Windows guest available