Saturday, November 14, 2026

ClickOnceBlobber for studying ClickOnce dependency hijacking and trusted-app covert channels

ClickOnceBlobber for studying ClickOnce dependency hijacking and trusted-app covert channels

ClickOnceBlobber repackages signed .NET ClickOnce deployments with a swapped dependency DLL, giving red teams a documented way to test application-reputation and egress-filtering controls.

Tooldazzyddos/ClickOnceBlobber — Python toolkit that backdoors signed .NET ClickOnce deployments via AppDomainManager dependency hijacking
Category.NET tradecraft / red team tooling / covert C2 channel research
Primary UseSimulating initial access through tampered ClickOnce packages in authorized engagements, specifically testing whether SmartScreen, EDR, and egress controls detect a hijacked AppDomainManager DLL and Azure Blob Storage tunneling
Safe UseFor authorized penetration tests, purple-team labs, and defensive research on .application deployment abuse; operators must only repackage applications they own or have written permission to test, and host tampered packages in lab infrastructure only
Telemetry NoteDefenders can watch for ClickOnce manifests whose SHA256 hashes were recalculated, .exe.config files declaring an AppDomainManager, strong-name publicKeyToken values zeroed in third-party DLLs, signed host binaries whose dependency manifest changed, and beaconing to *.blob.core.windows.net consistent with the proxyblob chunked-tunnel protocol

ClickOnceBlobber is a Python toolkit, currently at 169 stars, that demonstrates a specific and underappreciated abuse of Microsoft's ClickOnce deployment model. The core idea is that a legitimately signed ClickOnce application retains its reputation even when one of its dependency DLLs is replaced, because the host .exe stays untouched. The toolkit automates the mechanical parts of that tampering: swapping a DLL, injecting a .exe.config that names the payload as the AppDomainManager, and then rewriting the deployment manifests so the CLR accepts the modified package as internally consistent.

The technique it chains together is well worth understanding from a defensive standpoint, because each individual component is benign. ClickOnce itself is a one-click deployment technology that installs .application manifests without admin rights. AppDomainManager injection is a documented .NET extensibility mechanism where the CLR loads a custom manager before Main() ever executes. And the payload of choice here is a C# port of Quarkslab's open-source proxyblob agent, a SOCKS5 proxy that tunnels all traffic through Azure Blob Storage using blob chunks as a transport — meaning the compromised host talks only to *.blob.core.windows.net over HTTPS, a domain most corporate egress policies happily allow.

Architecturally, the repository is split between the clickonce_backdoor.py orchestration script and a set of example payloads under examples/. The payloads include ProxyBlobAgent.cs for the full ClickOnce integration, ProxyBlobStandalone.cs as a console-mode diagnostic build that logs packet types and connection events to stderr, ShellcodeLoader.cs as an alternative loader, and a benign MessageBoxPoC.cs whose only purpose is validating that the injection primitive works. The tiered payload design — prove injection first, then escalate to the real agent — mirrors how a careful operator would validate each stage independently in a lab before combining them.

The automation in clickonce_backdoor.py is substantial. Per the README, a single invocation generates C# source with operator settings baked in, compiles via the .NET Framework csc.exe, auto-installs BouncyCastle and ILMerge through NuGet into a local packages/ directory, merges the crypto dependency into a single DLL, replaces the target dependency, writes the .exe.config, patches both manifests, recalculates all SHA256 hashes and file sizes, strips code signatures, zeros the vendor publicKeyToken, and rewrites the deployment provider URL. That last pair of operations is notable: zeroing the strong-name token sidesteps RefDefValidation failures that would otherwise abort the install, and the hash recalculation is what keeps the tampered package from failing ClickOnce's own integrity checks.

Platform handling is done through a --platform flag passed straight to csc.exe /platform:. The agent code itself is architecture-neutral — no P/Invoke, no shellcode — so the flag only controls how the CLR decides to load it: x86 runs as 32-bit including under WoW64, x64 targets 64-bit hosts, and anycpu lets the runtime choose. The README correctly advises verifying the target binary with corflags.exe before selecting, since a mismatched platform selection simply produces a payload that never loads.

The most technically interesting section of the README is the porting narrative. Translating the Go proxyblob agent to C# surfaced three genuine cross-implementation bugs that anyone doing .NET crypto interop should internalize. First, Go's uuid.UUID stores bytes in big-endian RFC 4122 order while .NET's Guid constructor byte-swaps the first three components, silently corrupting wire-format connection IDs; the fix is raw byte[16] arrays. Second, BouncyCastle's ChaCha20Poly1305 only supports 12-byte IETF nonces, while the protocol needs XChaCha20's 24-byte nonces, requiring a hand-rolled HChaCha20 subkey derivation to bridge the two. Third, Go's base64.RawStdEncoding omits padding that .NET's decoder demands.

The wire protocol documented in the README is compact: a one-byte command, a 16-byte connection ID, a four-byte big-endian length, then variable payload, with commands NEW, ACK, DATA, and CLOSE. Session establishment uses an X25519 exchange with HKDF-SHA3-256 key derivation salted by the proxy's 24-byte nonce, and traffic is encrypted with XChaCha20-Poly1305. For defenders, this means the blob contents are opaque; detection has to rely on the transport pattern — periodic chunk reads and writes against a single storage container — rather than payload inspection.

The README also documents a subtle ILMerge failure mode that reads like hard-won debugging: ILMerge sets the internal assembly name from the output filename, not the input. If you merge to a temporary name and rename the file afterward, the CLR still reads the stale metadata, the .exe.config reference no longer matches, and the AppDomainManager injection fails silently with no error. The toolkit avoids this by merging directly to the final DLL name, and the troubleshooting table suggests ildasm /text piped through findstr .assembly as the diagnostic when injection mysteriously does nothing.

From a defensive research perspective, this tool is valuable precisely because it enumerates the artifacts tampering leaves behind. A repackaged ClickOnce deployment exhibits a signed host binary whose dependency manifest hashes differ from the vendor's published ones, a new .exe.config declaring an AppDomainManager, a third-party DLL with a zeroed strong-name token, and a deployment provider URL pointing somewhere other than the vendor's origin. Each of those is a concrete detection surface for endpoint tooling and for anyone monitoring .application distribution points, and the tool's built-in hosting mode with its specific MIME type mappings for .application, .manifest, and .deploy files is itself a recognizable lab artifact.

It is worth stating plainly that this is a dual-use offensive toolkit whose stated purpose is initial access simulation, and the README's walkthrough format makes that explicit. Everything documented here should be understood in the context of authorized engagements: operators repackaging applications they own, hosting outputs in lab infrastructure, and using diagnostic payloads like the message-box PoC before anything else. The bundled proxyblob integration works against local Azurite emulation, which means the entire chain can be exercised end to end without touching real infrastructure or any third party's applications.

ClickOnceBlobber ultimately earns its place in a study collection for the same reason proxyblob did: it takes several individually documented techniques — manifest tampering, AppDomainManager hijacking, trusted-domain C2 egress — and shows how they compose into a chain that signature-based controls struggle with individually. For red teams it is a well-engineered automation of a fiddly manual process; for blue teams it is effectively a specification of the exact telemetry a mature .NET monitoring program needs to catch this class of abuse.

Official project repository for dazzyddos/ClickOnceBlobber.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Sponsored
Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.