c62e2921e5c70fe3d9ba453a1a622f18ec6dd9d449bfb0640e6332fba6a34f2eunclassified-dotnet: c62e2921 — NModbus-embedded .NET PE with TripleDES crypto and reflective loading
Executive Summary
A .NET Framework PE32 (shipping_doc.exe) compiled in August 2024 that embeds the full open-source NModbus .NET library (industrial Modbus/TCP/RTU/ASCII protocol stack), references TripleDESCryptoServiceProvider, carries a high-entropy Base64 payload (232 bytes, ~6.2 bits entropy), and exhibits capa-detected reflective assembly loading, TCP socket creation, and Base64 decoding. The combination of ICS-protocol tooling with shipping-document social engineering and crypto primitives is anomalous — either an ICS-targeting implant or a stager whose payload leverages Modbus for lateral movement or C2 blending. No CAPE detonation available; all behavior inferred from static analysis. ^[file.txt] ^[capa.txt]
What It Is
| Field | Value | Source |
|---|---|---|
| SHA-256 | c62e2921e5c70fe3d9ba453a1a622f18ec6dd9d449bfb0640e6332fba6a34f2e |
^[metadata.json] |
| MD5 | 2491d7e865c008db077ae693a0c84f1a |
^[metadata.json] |
| Size | 1,931,264 bytes (1.84 MB) | ^[file.txt] |
| Type | PE32 executable (GUI) Intel 80386 Mono/.Net assembly, 3 sections | ^[file.txt] |
| Compile timestamp | Tue Aug 27 21:45:28 2024 UTC | ^[pefile.txt:34] ^[exiftool.json] |
| Filename (distribution) | shipping_doc.exe |
^[metadata.json] |
| Internal name | shipping doc.exe |
^[pefile.txt:239] |
| Version | 1.0.0.0 | ^[pefile.txt:237] |
| Copyright | Copyright © 2014 |
^[pefile.txt:239] |
| CompanyName | (empty) | ^[pefile.txt:235] |
| Entry point namespace | Zinmfx.Gsxgkr.Main |
^[r2:entry0] |
The binary is an unobfuscated CIL assembly with a single native import (mscoree.dll._CorExeMain), standard .NET PE structure, and no packing. ^[pefile.txt:255] ^[rabin2-info.txt] The .text section entropy is 7.97 — high but consistent with a large CIL image containing embedded library code, not with encrypted payload overlay. ^[pefile.txt:92]
How It Works
Build stack
- Compiler / runtime: .NET Framework (CIL,
lang: cilper radare2). Linker version 8.0. ^[rabin2-info.txt:11] ^[exiftool.json] - No packing / no obfuscation: All type and method names are visible in plaintext (though the application namespace
Zinmfx.Gsxgkris obfuscated/randomised). No ConfuserEx, SmartAssembly, or Xenocode signatures. Nodnfileparse failures. ^[strings.txt] ^[binwalk.txt] - No signing:
signed: falseper radare2; no certificate directory present. ^[rabin2-info.txt:27] - ASLR/DEP enabled:
DllCharacteristics: 0x8560=DYNAMIC_BASE | HIGH_ENTROPY_VA | NO_SEH | NX_COMPAT | TERMINAL_SERVER_AWARE. ^[pefile.txt:74]
Embedded library: NModbus
The binary contains the entire NModbus (v4.x) open-source .NET Modbus protocol library, including:
NModbus.FactoryExtensions— RTU/ASCII/TCP master and slave network factories ^[strings.txt:3561-3566]NModbus.IO.SocketAdapter,TcpClientAdapter,UdpClientAdapter— socket I/O wrappers ^[strings.txt:3541-3552]NModbus.Device.ConcurrentModbusMaster— async Modbus master with read/write register methods ^[strings.txt:3256]NModbus.Data.SlaveDataStore— in-memory coil/register data stores ^[strings.txt:3601-3602]NModbus.Extensions.Enron.EnronModbus— Enron Modbus extensions (32-bit registers) ^[strings.txt:3617-3620]- Full Modbus function code coverage: ReadCoils, ReadHoldingRegisters, WriteMultipleRegisters, ReadWriteMultipleRegisters, etc. ^[strings.txt:3179-3241]
NModbus is a legitimate ICS/SCADA protocol library. Its presence in a malware sample with a shipping-document lure is anomalous and strongly suggests ICS-targeting capability — either direct PLC manipulation or Modbus-over-TCP used as a covert C2 transport to blend with industrial traffic.
Cryptography
TripleDESCryptoServiceProviderreferenced in the CIL metadata. ^[strings.txt:3524]RijndaelandSystem.Security.Cryptographynamespace strings present. ^[strings.txt]- A 312-character Base64 string is embedded in the binary (decoded length 232 bytes, hex prefix
64 6b 8e 78...). Entropy ~6.2 bits/byte — too high for plaintext, not quite full-random, consistent with encrypted or compressed data. Not zlib-compressed. Not a PE or ELF header. ^[strings.txt] (manual extraction)
The Base64 payload has not been decrypted statically; the TripleDES key/IV are likely runtime-derived (e.g., from the obfuscated class constructors or from the Zinmfx.Gsxgkr namespace strings).
Capabilities flagged by capa
- DEFENSE EVASION:
T1140(Deobfuscate/Decode Files or Information),T1620(Reflective Code Loading),T1497.001(Virtualization/Sandbox Evasion — System Checks) - C2 / Communication: TCP socket creation (2×), send data (2×), receive data (2×), start TCP server
- Anti-VM: "reference anti-VM strings targeting Xen" — Note: No Xen/VMware/VirtualBox strings were recovered via
strings -elor radare2 string scans. These may be encoded inside the Base64 payload or matched by capa on obfuscated CIL patterns. Marked as unverified static inference. ^[capa.txt] - Data manipulation: Base64 decode (2×), PRNG (2×), .NET resource access (3×) ^[capa.txt]
Anti-analysis
- Namespace obfuscation: The application entry point is
Zinmfx.Gsxgkr.Main— a random alphanumeric namespace that bears no relation to theshipping docversion info. This is classic low-effort obfuscation to slow analyst identification. ^[r2:entry0] ^[strings.txt] - No debug info:
stripped: falsebut no PDB path, no debug directory. ^[rabin2-info.txt:30] - No standard .NET anti-tamper: No
SuppressIldasmAttribute, no ConfuserEx delegate chains observed in static strings.
Decompiled Behavior
Radare2 analysis (level 3) recovered 1,680 CIL functions. The entry point at 0x00402064 (Zinmfx.Gsxgkr.Main) is extremely short in decompilation — it allocates two obfuscated-type objects (\ue008.\ue000 and \ue008.\ue001) and passes the command-line arguments (arg0) into what appears to be a dispatch or initialization routine. The CIL decompilation is fragmented because radare2's CIL backend lacks register aliases (No SN reg alias for 'cil' warnings throughout analysis). ^[r2:entry0] ^[r2:sym...ctor__33]
The Zinmfx.Properties.Zidbn class (likely Resources) exposes getters for \ue002 through \ue004, suggesting the binary reads embedded .NET resources at runtime — consistent with capa's "access .NET resource (3 matches)". ^[strings.txt] ^[capa.txt]
C2 Infrastructure
No hardcoded IP addresses, domains, or URLs were recovered in static strings, ANSI strings, or Unicode strings. The binary's C2 is either:
- Encrypted inside the 232-byte Base64 blob (TripleDES-decrypted at runtime), or
- Resolved dynamically via Modbus/TCP traffic (the NModbus library supports runtime TCP endpoint configuration).
Capa detects "start TCP server" and TCP socket creation, suggesting the binary may listen for incoming connections rather than beacon outbound — a pattern more consistent with a RAT/listener than a traditional beaconing trojan. Alternatively, the NModbus library's TCP client adapter could be used to connect to a Modbus slave (PLC) as part of an ICS reconnaissance or sabotage payload.
Interesting Tidbits
- ICS protocol rarity: This is the first sample in the corpus to embed a full Modbus protocol stack. Previous ICS-related samples were Brazilian NFe certificate stealers (
nfedigitalcom) and Prometei Linux botnet. A .NET Modbus-capable binary is a new shape. ^[index.md] - Social-engineering mismatch: The
shipping doclure targets logistics/shipping professionals — a demographic that often has access to warehouse management systems, which may in turn interface with Modbus-enabled industrial controllers (conveyors, HVAC, SCADA gateways). The lure-theme-to-ICS-capability mapping may be deliberate. ^[social-engineering-filename-lure] - Base64 payload location: The 312-char Base64 string is stored as a plaintext Unicode string resource, not inside a manifest or RCData blob. This is lazy obfuscation — trivial to extract but the decryption key is not recoverable statically.
- Capa anti-VM caveat: The Xen-targeting anti-VM claim in capa could not be independently verified. If real, the strings are likely inside the encrypted payload. If false positive, it's from NModbus library internal error strings referencing "gateway" or "server" in contexts that capa's heuristic mistakes for hypervisor references.
- Linker version 8.0: Corresponds to Visual Studio 2005 / .NET 2.0 era tooling, but the binary is clearly a modern .NET Framework 4.x assembly. The linker version field is often untouched in IL-only PEs.
How To Mess With It (Homelab Replication)
Goal: Build a minimal .NET PE that embeds NModbus + TripleDES + Base64 payload, producing the same capa fingerprint.
- Toolchain: Visual Studio 2022 or
dotnet new winforms --framework net48 - Packages:
Install-Package NModbus(NuGet v4.0.0+),System.Security.Cryptography.TripleDES(built-in) - Code skeleton:
using NModbus; using System; using System.IO; using System.Net.Sockets; using System.Security.Cryptography; using System.Text; namespace Zinmfx.Gsxgkr { class Program { static void Main(string[] args) { var factory = new ModbusFactory(); var client = new TcpClient(); var master = factory.CreateMaster(client); var payload = Convert.FromBase64String("YOUR_BASE64_HERE"); using (var tdes = TripleDES.Create()) { tdes.Key = Encoding.UTF8.GetBytes("derive_key_here_"); tdes.IV = new byte[8]; var decrypted = tdes.CreateDecryptor().TransformFinalBlock(payload, 0, payload.Length); var asm = System.Reflection.Assembly.Load(decrypted); asm.EntryPoint.Invoke(null, new object[] { args }); } } } } - Verification: Run
capa <repro.exe>. Expect hits on:compiled to the .NET platformcreate TCP socketdecode data using Base64 in .NETload .NET assemblyinvoke .NET assembly methodgenerate method via reflection in .NET
Deployable Signatures
YARA rule
rule UnclassifiedDotnetNModbusShippingDoc {
meta:
description = ".NET PE with embedded NModbus library, shipping_doc lure, and TripleDES crypto"
author = "PacketPursuit"
date = "2026-06-22"
sha256 = "c62e2921e5c70fe3d9ba453a1a622f18ec6dd9d449bfb0640e6332fba6a34f2e"
strings:
$nmodbus1 = "NModbus.FactoryExtensions" ascii wide
$nmodbus2 = "NModbus.IO.TcpClientAdapter" ascii wide
$nmodbus3 = "NModbus.Device.ConcurrentModbusMaster" ascii wide
$nmodbus4 = "NModbus.Extensions.Enron.EnronModbus" ascii wide
$crypto1 = "TripleDESCryptoServiceProvider" ascii wide
$crypto2 = "Rijndael" ascii wide
$lure1 = "shipping doc" ascii wide
$lure2 = "shipping doc.exe" ascii wide
$b64_blob = "ZGuOeEGYGUCYakiQVGaUY0rbdmGOaUmXW2vGS0GBcnyJfl20RGGYYUaZTimaaVCqcWeRYGqUWnfGY1SqfnyYfVGUW3uJdR+SUmaiQEGbUGaVN2OQQ0aEfEGzRX2QREWbU36YN0OQQ02zbUmQDFuTaEGNeHTGXkGUU0GJfk2bUCm8aEDOUHeJU3SaRHuJZUubDHWYeHu2QmCPaUqBc32QbU2bDEGYeGCUQ3PGPhLMByfGTVeGUn+fYF2mUmCLaVbOZHuQfEiQdmGOaUmXW2u4dFSZWGCYfh+XVnCYYFKYDGGQY0+QQ3eOeA==" ascii wide
$entry_ns = "Zinmfx.Gsxgkr.Main" ascii wide
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and
(
($lure1 or $lure2) and
($crypto1 or $crypto2) and
2 of ($nmodbus*) and
any of ($b64_blob, $entry_ns)
)
}
Behavioral hunt query (KQL / Microsoft Sentinel)
// .NET process with shipping_doc.exe filename AND Modbus/TCP network activity
let modbus_ports = dynamic([502, 503, 1502, 1700, 1800, 1883, 2404, 44818]); // common Modbus/ICS ports
DeviceNetworkEvents
| where InitiatingProcessFileName contains "shipping_doc" or InitiatingProcessFileName contains "shipping_doc.exe"
| where RemotePort in (modbus_ports)
| summarize count() by DeviceName, InitiatingProcessAccountUpn, RemoteIP, RemotePort, InitiatingProcessCommandLine
| where count_ > 0
IOC list
| IOC | Type | Notes |
|---|---|---|
c62e2921e5c70fe3d9ba453a1a622f18ec6dd9d449bfb0640e6332fba6a34f2e |
SHA-256 | Sample binary |
2491d7e865c008db077ae693a0c84f1a |
MD5 | Sample binary |
shipping_doc.exe |
Filename | Distribution lure name |
Zinmfx.Gsxgkr.Main |
.NET namespace | Entry point; randomised/obfuscated |
NModbus |
Library | Full Modbus protocol stack embedded |
TripleDESCryptoServiceProvider |
API | Crypto primitive referenced |
Base64 payload (see YARA $b64_blob) |
Encrypted blob | 232 bytes decoded; key unknown |
Behavioral fingerprint statement
This .NET PE presents as shipping_doc.exe with empty CompanyName and a 2014 copyright. It embeds the full NModbus .NET library for Modbus/TCP/RTU/ASCII industrial protocol communication. At runtime it allocates obfuscated-type objects from the Zinmfx.Gsxgkr namespace, accesses embedded .NET resources, decodes a 232-byte Base64 payload (likely TripleDES-encrypted), and uses reflection to load and invoke .NET assemblies. Network behavior includes TCP socket creation and potentially starting a TCP listener (Modbus server mode). No hardcoded C2 endpoints are visible statically. The combination of shipping-document social engineering with ICS protocol capability is the distinguishing anomaly.
Detection Signatures
| Tactic | Technique | Evidence | Confidence |
|---|---|---|---|
| DEFENSE EVASION | T1140 Deobfuscate/Decode Files or Information | Base64 decode + TripleDES crypto in .NET | Medium |
| DEFENSE EVASION | T1620 Reflective Code Loading | capa: "load .NET assembly", "invoke .NET assembly method", "generate method via reflection" | Medium |
| DEFENSE EVASION | T1497.001 Virtualization/Sandbox Evasion — System Checks | capa anti-VM Xen strings claim (unverified static) | Low |
| COMMAND AND CONTROL | — | TCP socket creation, start TCP server (capa) | Medium |
| DISCOVERY | — | Modbus register/co read/write capability via NModbus | Medium (ICS inference) |
References
- Artifact ID:
f0f40e77-9cff-44bf-b4ce-8ae74aad4914(OpenCTI) - Source: MalwareBazaar via OpenCTI connector
- NModbus library: https://github.com/NModbus/NModbus (open-source .NET Modbus implementation)
- Related wiki pages:
- unclassified-dotnet — umbrella entity for unattributed .NET malware
- social-engineering-filename-lure — shipping/document lure pattern
Provenance
Analysis based on static triage artifacts: file.txt, pefile.txt, exiftool.json, metadata.json, strings.txt, capa.txt, rabin2-info.txt, binwalk.txt. Radare2 level-3 analysis performed on the live binary (/tmp/c62e2921...bin) with CIL backend. No CAPE detonation available (no Windows guest). dnfile not installed; CIL metadata read via radare2 exports and strings -el. All capa claims treated as static inference and caveated where unverifiable.