typeanalysisfamily54e64econfidencemediumdotnetloadercrypterc2defense-evasioncommunicationmalware-family
SHA-256: e14cb7f34407a042fc6a20aebd73d36b0d7a91a724872988ec08e7e4e39934a6

54e64e: e14cb7f3 — .NET ILRepack crypter with AES-Z85-JC-1-2 decryptor, MES WCF C2

Executive Summary

A .NET Framework 4.7.2 PE crypter/loader built with ILRepack merging, masquerading as an auto-updater framework (MQCommon.UI.AutoUpdater). It embeds a custom AES-Z85-column-permutation decryption DLL (JC-1-2) and carries an XML config pointing to a Manufacturing Execution System (MES) WCF C2 endpoint (mes.zy.com). OpenCTI labels it 54e64e / dropped-by-amadey. This is the first .NET morph in the 54e64e cluster, distinct from prior MSVC C++ and Go infostealer builds. Static-only; CAPE skipped (no Windows guest).


What It Is

Field Value
SHA-256 e14cb7f34407a042fc6a20aebd73d36b0d7a91a724872988ec08e7e4e39934a6
File type PE32+ executable (GUI) x86-64 Mono/.Net assembly ^[file.txt]
Size 1,721,344 bytes (1.64 MB) ^[exiftool.json]
Target framework .NET Framework 4.7.2 ^[strings.txt:1442]
Compiler C# compiled to IL, then merged with ILRepack ^[strings.txt:1445]
PDB path C:\Users\Administrator\AppData\Local\Temp\2\LX_QhSq5nqlwW05f\ILRepack-11348-327298\LX_QhSq5nqlwW05f.pdb ^[rabin2-info.txt]
Timestamp PE header: 2046-05-30 (fabricated) ^[pefile.txt]; Debug dir: 2026-05-28 ^[pefile.txt:300]
Signing Unsigned ^[pefile.txt]
Packing None on outer PE; inner assemblies merged via ILRepack
Family 54e64e (OpenCTI label) — this is the seventh confirmed morph in the cluster

Build toolchain fingerprint:

  • ILRepack (version not stated) merged at least two assemblies: the main MQCommon.UI.AutoUpdater payload and the JC-1-2 decryption DLL. ^[strings.txt:1066,1127]
  • The LX_QhSq5nqlwW05f random prefix in the PDB path is consistent with ILRepack temp-file naming when merging with randomized output names. ^[strings.txt:1445]
  • No obfuscation beyond the merged-name randomization; all type and method names remain plaintext in the IL metadata.

Embedded artefacts (binwalk):

  • PNG icon, 48×48, at offset 0xA8AD ^[binwalk.txt]
  • XML config at 0xBA36 ^[binwalk.txt]
  • Second PE (the JC-1-2 DLL) at 0xBCF3 ^[binwalk.txt]
  • AES S-Box tables at 0xE92B ^[binwalk.txt]
  • Second XML document at 0x1A4117 ^[binwalk.txt]

How It Works

1. Masquerade & Surface

The binary presents as a legitimate auto-updater / PDF-diagram library hybrid:

  • Internal namespace: QCommon.UI.UltimateKtv (Karaoke TV / entertainment software theme) ^[strings.txt:1359]
  • Assembly product: MQCommon.UI.AutoUpdater v1.0.7.0 ^[strings.txt:170]
  • WinForms GUI elements: progressBar1, timer1, backgroundWorker1, pictureBox1, btnOk, btnCancel ^[strings.txt:232-238]
  • PDF library class names (PdfPageTreeNode, PdfRectangle, PdfDictionary, PdfCatalog) suggest a diagramming / PDF-rendering library was merged in to provide UI scaffolding and plausible cover. ^[strings.txt:469-490]

2. Crypto Pipeline

The payload decryption uses a custom three-layer cipher chain found in the JC-1-2 embedded DLL:

  1. Z85 encoding (ZeroMQ Base-85) — cipherZ85, DecryptZ85, Z85Chars, Z85Decode ^[strings.txt:52,53,81,136]
  2. AES column permutation — AesPowder, InvColPerm, colPerm, ColumnPermute, InvShiftRows, InvMixColumns, InvSubBytes ^[strings.txt:121,114,115,100,141,135,132]
  3. PKCS#7 padding strip — stripPkcs7, Pkcs7Unpad ^[strings.txt:58,77]

Static array initialization types (__StaticArrayInitTypeSize=24, =16, =256) match AES-128/256 round-key sizes. ^[strings.txt:51-55]

Key material: The binary stores ten hardcoded 64-character hex strings that likely serve as decryption keys or integrity hashes. ^[strings.txt:43-49,55-63]

3. Embedded Decryptor DLL

The JC-1-2 DLL is embedded as a second PE inside the main executable (offset 0xBCF3). It is extracted at runtime, written to a temp path, and loaded via reflection:

  • ExtractEmbeddedJcDecryptorDll → LoadJcDecryptorDll → JcDecryptorAssembly ^[strings.txt:857,856,1398]
  • The decryptor is referenced through JC_1_2_1.JC_1_2.dll and JC_1_2.dll strings. ^[strings.txt:858,112]

4. Update / C2 Mechanism

The binary reads an embedded XML config that defines a client-mode update server:

<Config>
  <Enabled>true</Enabled>
  <WorkMode>Client</WorkMode>
  <UpdateFilePath>d:\DATAWEB\mes</UpdateFilePath>
  <ServerPath>http://<lan>/Mes.WCF/MSI/MES</ServerPath>
  <ServerUrl>http://mes.zy.com/MES.Wcf/MSI/MES/AutoupdateService.xml</ServerUrl>
</Config>

^[strings.txt:26-37]

C2 observations:

  • The ServerPath uses an internal IP (<lan>) suggesting deployment inside a target network or a test environment. ^[strings.txt:35]
  • The ServerUrl resolves to a public domain: mes.zy.com with a WCF SOAP endpoint path (/MES.Wcf/MSI/MES/AutoupdateService.xml). ^[strings.txt:36]
  • WorkMode = Client indicates the binary expects to poll a server for updates, download payloads, and execute them. ^[strings.txt:33]
  • The UpdateFilePath points to d:\DATAWEB\mes — a hardcoded staging directory on the D: drive, suggesting pre-configuration for a specific victim environment. ^[strings.txt:34]
  • MES in this context is Manufacturing Execution System, a common industrial/OT software suite. The WCF service naming convention (MES.Wcf/MSI/MES) is consistent with MES product update channels. This implies OT/ICS targeting or masquerade of an industrial auto-updater.

5. Runtime Behavior (inferred from capa + strings)

  • File system operations: Creates directories (CreateDirectory ×11), checks existence, moves/deletes files, copies files (FileCoppy sic), writes files (WriteAllBytes, WriteFile). ^[capa.txt]
  • Process execution: Spawns child processes with ProcessStartInfo and CreateProcess equivalents (via .NET Process class). ^[capa.txt]
  • PowerShell invocation: run PowerShell expression hit in capa. Likely used to execute downloaded payloads or bypass restrictions. ^[capa.txt]
  • HTTP download: DownloadFileAsync, DownloadProgressChanged, WebClient, DownloadString, HttpWebRequest pattern. ^[strings.txt:302,337,1272]
  • Reflective assembly loading: Assembly.Load(byte[]) equivalent via GetManifestResourceStream and JcDecryptorAssembly. ^[capa.txt]
  • MD5 integrity checks: MD5CryptoServiceProvider, ComputeHash, HashMD5Encrypt, HashCodeMD5Encrypt. ^[strings.txt:1017,762,1311,1312]
  • Privilege checks: GetCurrentPrivilegeLevel, WindowsPrincipal, SecurityPrivilegeLevel, ElevatedExecutionPolicy. ^[strings.txt:851,838,852,1386]
  • Registry read: Win32_OperatingSystem and WMI queries not directly observed, but System.Security.Principal and privilege evaluation suggest UAC/elevation awareness. ^[strings.txt]

Decompiled Behavior

Ghidra/r2 decompilation was unavailable (MCP server down during this analysis). The following is reconstructed from IL metadata strings, capa capability mapping, and binwalk artefact offsets.

Entry-point flow (inferred):

  1. Program+<Main>d__0 — async entry point. ^[strings.txt:1437]
  2. InitializeComponent — sets up WinForms UI (progress bars, labels, timers). ^[strings.txt:1284]
  3. LoadConfig → UpdateConfig → reads embedded XML from resources. ^[strings.txt:717,718]
  4. If Enabled==true and WorkMode==Client: a. CheckUpdateFiles — enumerates server-side manifest. ^[strings.txt:1144] b. ProcDownload / StartDownload / DownloadFileAsync — pulls payload via HTTP. ^[strings.txt:325,326,327,302] c. FileAdd / MoveFolderToOld / ClearOld — stages and replaces local files. ^[strings.txt:331,370,371] d. ExecuteIntegrationRoutine / ExecuteBatch / ExecuteSilent — runs the downloaded payload. ^[strings.txt:603,757,1273]
  5. CleanupTransientFiles — removes staging debris. ^[strings.txt:1146]
  6. RollBack — restores prior state on failure. ^[strings.txt:808]

Crypto invocation chain:

  1. DecryptPayloadWith → DecryptZ85WithDll → ExtractEmbeddedJcDecryptorDll → LoadJcDecryptorDll → JC-1-2 DLL loaded via reflection. ^[strings.txt:800,855,857,856]
  2. The decryptor DLL exposes DecryptFileTo, DecryptBytes, CbcDecryptBuffer. ^[strings.txt:120,134,122]
  3. GetPcmDataKeyIv and GetPcmDataCipher retrieve key/IV and ciphertext from embedded resources or remote download. ^[strings.txt:1357,1041]

C2 Infrastructure

Indicator Value Type Provenance
Primary C2 (public) http://mes.zy.com/MES.Wcf/MSI/MES/AutoupdateService.xml WCF SOAP endpoint ^[strings.txt:36]
Secondary C2 (internal) http://<lan>/Mes.WCF/MSI/MES HTTP service ^[strings.txt:35]
Staging path d:\DATAWEB\mes Local directory ^[strings.txt:34]
Work mode Client Config flag ^[strings.txt:33]

No hardcoded credentials, mutex names, or named pipes observed. The C2 is fully config-driven via the embedded XML.


Interesting Tidbits

  1. Industrial MES masquerade. The mes.zy.com domain and MES.Wcf path strongly suggest the author is mimicking or targeting a Manufacturing Execution System (MES) product used in OT/ICS environments. This is a notable pivot from the prior consumer/IT-focused 54e64e morphs. ^[strings.txt:36]

  2. Administrator build environment. The PDB path references C:\Users\Administrator\AppData\Local\Temp\2\..., indicating the binary was built on a Windows Server or RDP session with the default Administrator account. The Temp\2 subfolder is the Windows Terminal Services per-session temp directory for session ID 2. ^[strings.txt:1445]

  3. ILRepack temp-file prefix. The LX_QhSq5nqlwW05f prefix in the PDB is a randomized ILRepack output name; it does not appear in strings outside the debug directory, suggesting the author ran ILRepack with default random-naming behavior. ^[strings.txt:1445]

  4. Typo in code. FileCoppy (sic) appears in the strings, suggesting the author is not a native English speaker or copy-pasted from a non-English source. ^[strings.txt:1403]

  5. Empty version info. The VS_VERSIONINFO block has all fields zeroed (FileVersion: 0.0.0.0, ProductVersion: 0.0.0.0, empty FileDescription and LegalCopyright). ^[pefile.txt:174-225] This is consistent with the 54e64e cluster's pattern of minimal or fabricated version metadata.

  6. Custom AES variant. The AesPowder / InvColPerm / ColumnPermute naming suggests a non-standard AES implementation with added column-permutation layers, likely designed to evade standard AES decryption tools. ^[strings.txt:121,114,100]

  7. Embedded second PE. The JC-1-2 DLL is a complete PE embedded at 0xBCF3. It is not stored as a .NET resource but appears to be appended after the main PE sections, evading simple resource-only extraction. ^[binwalk.txt]

  8. No .NET obfuscation. Unlike many .NET crypters, this sample has no ConfuserEx, SmartAssembly, or Xenocode obfuscation. The IL metadata is fully readable. The only obfuscation is the ILRepack merge and the randomized temp-name prefix. ^[strings.txt]


How To Mess With It (Homelab Replication)

Goal: Build a .NET auto-updater shell that mimics the capa fingerprint of this sample.

Toolchain:

  • Visual Studio 2022 or dotnet CLI targeting .NET Framework 4.7.2
  • ILRepack NuGet package (ILRepack.Lib.MSBuild.Task or ILRepack CLI)
  • A dummy WinForms app with ProgressBar, BackgroundWorker, and WebClient

Steps:

  1. Create a C# WinForms project with a progress bar and download button.
  2. Add WebClient.DownloadFileAsync to pull a file from a test HTTP server.
  3. Add Process.Start to execute the downloaded file.
  4. Add a second Class Library project with a dummy Decrypt method.
  5. Build both, then merge with ILRepack:
    ilrepack.exe /out:MergedUpdater.exe /wildcards MainApp.exe *.dll
    
  6. Verify the merged binary shows ILRepack temp strings in the PDB path (if debug build).
  7. Run capa MergedUpdater.exe and compare to this sample's capa.txt — expect hits on run PowerShell expression, create process, receive data, read HTTP header, load .NET assembly.

What you'll learn: How ILRepack merging affects static analysis visibility, how capa scores merged .NET binaries, and how to distinguish merged assemblies from natively compiled ones.


Deployable Signatures

YARA Rule

rule ILRepack_54e64e_MES_Updater
{
    meta:
        description = "54e64e .NET ILRepack crypter with JC-1-2 decryptor and MES WCF C2"
        author = "PacketPursuit"
        date = "2026-08-11"
        sha256 = "e14cb7f34407a042fc6a20aebd73d36b0d7a91a724872988ec08e7e4e39934a6"
        family = "54e64e"
    strings:
        $ns1 = "QCommon.UI.UltimateKtv" wide ascii
        $ns2 = "MQCommon.UI.AutoUpdater" wide ascii
        $dll1 = "JC_1_2.dll" wide ascii
        $dll2 = "JC-1-2" wide ascii
        $c1 = "cipherZ85" wide ascii
        $c2 = "DecryptZ85" wide ascii
        $c3 = "AesPowder" wide ascii
        $c4 = "stripPkcs7" wide ascii
        $xml1 = "<WorkMode>Client</WorkMode>" wide ascii
        $xml2 = "MES.Wcf/MSI/MES" wide ascii
        $pdb1 = "ILRepack-" wide ascii
        $pdb2 = "LX_QhSq5nqlwW05f" wide ascii
    condition:
        uint16(0) == 0x5A4D and
        (2 of ($ns*) or 2 of ($dll*)) and
        (2 of ($c*) or $xml2) and
        filesize < 3MB
}

Sigma Rule (Process Creation)

title: 54e64e MES WCF Updater Child Process
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    ParentImage|endswith:
      - '\\LX_QhSq5nqlwW05f_i.exe'
      - '\\MQCommon.UI.AutoUpdater.exe'
    CommandLine|contains:
      - 'powershell'
      - 'd:\\DATAWEB\\mes'
  condition: selection
falsepositives:
  - Unknown
level: high

Behavioral Hunt Query (KQL / Microsoft Sentinel)

let target_domains = dynamic(["mes.zy.com"]);
DeviceNetworkEvents
| where RemoteUrl contains "MES.Wcf" or RemoteUrl contains "AutoupdateService.xml"
| where RemoteUrl has_any (target_domains)
| summarize count() by DeviceName, RemoteUrl, InitiatingProcessFileName, InitiatingProcessCommandLine

IOC List

Indicator Value Type
SHA-256 e14cb7f34407a042fc6a20aebd73d36b0d7a91a724872988ec08e7e4e39934a6 Hash
MD5 e12c15a44a735975ca2d15d93cbc9c95 Hash
ssdeep 24576:n+z+pHCbOUNYb6ILacgNzGHnueBCezOGof0xcM:/HnUNYmIWbA5Cea5c Fuzzy hash
Domain mes.zy.com C2 domain
URL http://mes.zy.com/MES.Wcf/MSI/MES/AutoupdateService.xml C2 endpoint
Internal IP <lan> C2 (internal)
Staging dir d:\DATAWEB\mes Local path
Embedded DLL JC-1-2 / JC_1_2.dll Payload decryptor
PDB artifact LX_QhSq5nqlwW05f Build temp name
Namespace QCommon.UI.UltimateKtv .NET namespace
Assembly MQCommon.UI.AutoUpdater .NET assembly name

Behavioral Fingerprint Statement

This binary is a .NET Framework 4.7.2 GUI executable merged with ILRepack. On launch it initializes a WinForms progress-bar UI, reads an embedded XML config specifying a MES WCF update server, and begins an async download loop via WebClient.DownloadFileAsync. Before executing downloaded content, it extracts an embedded JC-1-2 DLL from its own body at offset 0xBCF3, loads it via reflection, and invokes AES-Z85-column-permutation decryption routines to decrypt the payload. The binary may spawn PowerShell or child processes to execute the decrypted payload, and it cleans up transient staging files on completion. Network traffic is directed to mes.zy.com or a hardcoded internal IP (<lan>) over HTTP WCF SOAP paths. No Authenticode signature is present.


Detection Signatures (capa → ATT&CK)

capa capability ATT&CK ID Description
run PowerShell expression T1059.001 PowerShell execution
load .NET assembly T1620 Reflective code loading
create process in .NET T1106 Native API execution
receive data T1071 C2 communication
read HTTP header / set HTTP header T1071.001 Web protocols
hash data with MD5 — Integrity verification
check file extension / check if file exists T1083 File discovery
get hostname / get session user name T1082 System info discovery
find graphical window T1010 Application window discovery
access .NET resource — Embedded payload extraction
manipulate unmanaged memory T1055 Process injection potential
create directory / delete file / move file — File staging
copy file — Payload staging
write file in .NET — Payload drop
suspend thread — Process manipulation
terminate process — Cleanup

References


Provenance

Analysis derived from static artefacts generated by the triage pipeline on 2026-05-28 and reviewed on 2026-08-11. Tools: file (file type), pefile (PE header), exiftool (metadata), strings (raw string extraction), floss (failed — no decoded strings recovered due to .NET IL metadata), capa v6.0+ (capability mapping), binwalk (embedded artefact extraction), radare2 (rabin2 binary info — full r2 decompilation unavailable due to MCP server outage). No dynamic execution (CAPE skipped — no Windows guest). All claims cite provenance markers above.