What Socket found (and what is confirmed)#
Socket’s Threat Research Team reports it identified five malicious NuGet packages published from a single account. The packages impersonate Chinese .NET UI and infrastructure libraries and are described as “functional” libraries that compile cleanly while also delivering an information-stealing payload.
Socket says the operator’s approach is not a simple “typo of a popular public package” in every case. Instead, some package IDs appear designed to look like private or internally distributed libraries used in Chinese enterprise environments. That makes the names plausibly “normal” to developers working inside those ecosystems.
One package name highlighted by Socket is “DantUI,” described as a one-character anagram of “AntdUI,” an MIT-licensed WinForms component library maintained on Gitee. Socket says its analysis of a source diff (e.g., against a file under DantUI/Svg/Transforms/SvgTransform.cs) supports a repackaging technique: the malicious package is based on a decompiled copy of a legitimate library, then wrapped with protection/packing that enables hidden payload behavior.
Socket reports that across all versions the five packages accumulated about 65,000 downloads. Socket also states that, at the time of writing, all five packages remained available on NuGet and that it submitted takedown requests to the NuGet Gallery security team.
How the packages try to look legitimate#
A key detail in Socket’s writeup is that these packages are not “empty shells.” They contain working .NET code under expected namespaces and patterns (including what Socket describes as service/infrastructure patterns consistent with internal enterprise libraries). That matters for two reasons:
First, functional code lowers suspicion. The consumer gets a library that behaves like a normal dependency—build passes, APIs exist, nothing obviously breaks.
Second, functional code makes the attack more durable. If the dependency is truly used in a project, it is more likely to be restored, built, and loaded repeatedly across environments (developer workstations, CI/CD runners, and build servers).
Socket also points to publishing behavior as part of the “legitimacy mask.” The account reportedly owns exactly these five package IDs and no others, with no benign “cover” packages and no history predating the campaign.
More importantly, Socket describes a large version history: 224 total versions across the five package IDs, with 219 versions unlisted. Unlisted NuGet packages can still be installed if you know the exact ID and version. In other words, the packages can be kept out of casual discovery while remaining usable in environments that already reference them (especially if version-pinned).
Evasion via version rotation (why hashes won’t save you)#
Socket describes an “active evasion” workflow: keeping only one version listed per package at a time while rotating versions when analysis begins.
The reported sequence is straightforward:
- A given version is listed and gets installed.
- Once defenders begin to analyze and block that version (often using hashes), the operator publishes a new version and unlists the analyzed one.
- The DLL bytes change across versions, so file-hash IOCs become stale quickly.
Socket gives an example: version 2.1.55 published on 2026-04-14, then rotations to 2.1.56 and 2.1.57 after analysis began. It also notes this pattern appears across the broader unlisted version history, which Socket interprets as evidence the operator has been running the rotation cycle for months.
Socket also flags a “release pipeline” signal: five versions published in sequence in a short time window, in a dependency-graph-respecting order (core packages before consumers). The timing and order are described as consistent with scripted publishing rather than manual, ad hoc uploads.
Practical implication: if your defenses rely mainly on blocklists of known-bad package hashes or a single pinned “safe” version check, this campaign is designed to outpace you.
Payload and execution path (as described)#
Socket attributes the payload behavior to a .NET Reactor–protected infostealer grafted onto the repackaged libraries. Reactor is commonly used as a protector/obfuscator; here, Socket says it is used to decrypt and restore method bodies at runtime and to hide malicious logic from static inspection.
Socket describes a stage where encrypted IL is decrypted at JIT time. In its description, the protected assembly:
- Uses a .NET module initializer so code runs automatically when the assembly is loaded (before application logic runs).
- Performs anti-tamper integrity checks using an embedded RSA public key.
- Allocates memory with execute permissions (e.g., via
VirtualAlloc(PAGE_EXECUTE_READWRITE)). - Decrypts an encrypted payload blob and installs a hook that gains control over subsequent method compilation in the process.
The high-level point is not the exact mechanism (which can vary), but the operational effect: simply restoring/building/loading the dependency can be enough to execute malicious behavior. There may be no explicit API call in your code that “triggers” the malware beyond referencing the assembly.
Socket reports that the stealer targets saved credentials across multiple browsers, cryptocurrency wallets (desktop and browser extensions), SSH keys, and local files, and exfiltrates to a newly registered command-and-control domain.
Why it matters for developers and CI/CD (not just end-user machines)#
Supply-chain attacks against developer dependencies have a predictable blast radius:
- Developer workstations: credentials stored in browsers, SSH keys, tokens, and local config files can be exposed.
- CI/CD runners and build servers: secrets are often present in environment variables, build caches, artifact signing workflows, or deployment contexts.
- Downstream users: if a compromised build pipeline produces releases with altered artifacts, impact can propagate beyond the initial machine.
Socket’s writeup emphasizes that “no explicit user interaction” is required once the assembly is loaded. If accurate, that raises the risk profile for automated systems: build steps that restore and compile dependencies can still end up loading assemblies (tests, analyzers, tooling, design-time tasks), and that can be enough.
The campaign’s targeting theme also matters: developers in Chinese enterprise .NET ecosystems (or organizations that consume packages from internal/curated registries influenced by that ecosystem) may be more likely to accept the package naming, namespaces, and library surface as legitimate.
What not to overclaim#
The source describes strong indicators of malicious behavior and provides a detailed technical narrative, but there are still boundaries you should keep clear when communicating internally:
- Don’t assume every download equals a compromised machine. Downloads are exposure, not proof of execution.
- Don’t assume which specific organizations were targeted unless you have your own telemetry. The source infers intended victims based on naming and ecosystem signals.
- Don’t treat hash-based IOCs as durable in a version-rotation campaign. They can still help for point-in-time containment, but they are not a long-term control.
- Don’t assume takedown has happened. Socket states the packages were still available at the time of writing and that takedown requests were submitted.
Practical checks and mitigations you can apply now#
If you run .NET builds that consume NuGet packages (especially in environments with mixed public/private feeds), the fastest useful steps are operational, not theoretical:
-
Audit package restore logs and lock files
Checkpackages.lock.json,PackageReferencehistory, and your restore logs for unfamiliar package IDs—especially those that look like enterprise/internal components but originate from public NuGet. -
Identify unlisted-version risk
If you pin versions explicitly, review whether any dependencies are being installed from unlisted versions. Unlisted does not equal malicious, but it should increase scrutiny. -
Add controls beyond hashes
Prefer allowlists for what feeds and package IDs are permitted in CI. Consider policy checks that evaluate publisher metadata, sudden version churn, and “newly created package + high version count” patterns. -
Isolate build secrets
Treat build runners as high-risk endpoints. Minimize long-lived secrets on runners, rotate credentials, and restrict outbound network access where possible (egress controls can limit C2 communications even if something executes). -
Triage any suspected exposure
If you find one of the reported package IDs in a project, assume the developer machine and associated CI runners may need incident handling: credential rotation, workstation inspection, and review of recent release artifacts.
Socket’s report is a reminder that “looks like a normal dependency” is no longer a meaningful safety signal. In modern .NET supply-chain attacks, functionality is part of the camouflage.