Keypoints
- ReversingLabs linked a coordinated campaign (starting August) that published hundreds of malicious NuGet packages, including typosquatted names like ZendeskApi.Client.V2, Betalgo.Open.AI and Forge.Open.AI.
- Threat actors shifted from using tools/init.ps1 and install.ps1 PowerShell scripts to placing malicious code inside .targets files under the package “build” directory, leveraging MSBuild integrations.
- The malicious .targets files contain inline tasks that download a stage‑2 executable (previously from attacker IPs, later from throwaway GitHub repos) and execute it in a new process.
- Obfuscation tactics included hiding code off-screen with spaces/tabs and embedding obfuscated command lines as resources in the .NET stage‑2 payload.
- Over 700 malicious packages were detected in the August wave; ReversingLabs reported the new packages and NuGet removed them shortly after detection.
- Visual Studio can still execute deprecated init.ps1 scripts on install, making both init.ps1 autorun and MSBuild .targets inline tasks viable execution vectors for attackers.
MITRE Techniques
- [T1195] Supply Chain Compromise – Attackers published and typosquatted NuGet packages to introduce malicious code into developer projects; quote: ‘typosquatting on popular Nuget packages named ZendeskApi.Client, Betalgo.OpenAI and Forge.OpenAI.’
- [T1059.001] Command and Scripting Interpreter: PowerShell – Earlier stages used PowerShell scripts in tools (init.ps1/install.ps1) to download and run payloads; quote: ‘downloader functionality was placed into PowerShell scripts located inside the “tools” directory… init.ps1, install.ps1 and uninstall.ps1 scripts, which are run on certain events.’
- [T1105] Ingress Tool Transfer – Packages downloaded stage‑2 executables from remote locations (attacker IPs or throwaway GitHub repos) and executed them; quote: ‘it downloads an executable from a remote location and executes it in a new process’ and ‘fetching the stage 2 malware payload from the newly created, throwaway GitHub repository.’
- [T1027] Obfuscated Files or Information – Authors obfuscated payloads and concealed malicious code (off‑screen spacing/tabs and embedded obfuscated command lines in .NET resources); quote: ‘Stage 2 malware was a .NET executable which executes an obfuscated command line embedded as a resource’ and ‘using spaces and tabs to move it outside of the content visible within the default screen width.’
- [T1574] Hijack Execution Flow – Abuse of MSBuild integrations/.targets import to execute inline tasks during the build process, causing malicious code in imported .targets files to run whenever the project is built; quote: ‘MSBuild files can include inline tasks, which can contain executable code… every time package A is built, inline tasks from the imported .targets file will get executed.’
Indicators of Compromise
- [NuGet package names] Malicious/typosquatted packages used in the campaign – Pathoschild.Stardew.Mod.Build.Config (v6.5.3), ZendeskApi.Client.V2 (v6.0.0), and many others (dozens listed).
- [SHA1 hashes] Package file hashes associated with malicious releases – c6f7dc7f9e2a5447f966f582d4fe41869ee07275 (Pathoschild.Stardew.Mod.Build.Config v6.5.3), 8a1d7189b2e4547ab730397fe1e95898474c1f41 (ZendeskApi.Client.V2 v6.0.0), and many more hashes in the provided table.
Attackers exploited NuGet’s MSBuild integrations by placing malicious .targets files in the package “build” directory. When NuGet installs a package that contains build files, MSBuild adds an to the consuming project, which causes any inline tasks inside the imported .targets/.props files to run at build time. The observed .targets files include a property containing inline task code that downloads a stage‑2 executable and launches it in a new process, effectively enabling arbitrary code execution during normal project builds.
Earlier waves of the campaign relied on autorun PowerShell scripts inside the package “tools” directory (init.ps1/install.ps1/uninstall.ps1), which Visual Studio can still execute on package events despite deprecation. Operators adapted after takedowns by moving from init.ps1-based downloaders to the more stealthy .targets inline tasks, and by hosting stage‑2 payloads on throwaway GitHub repositories. Stage‑2 artifacts were .NET executables that executed obfuscated command lines embedded as resources.
To evade detection the threat actors typosquatted popular package names, inflated download counts, and used formatting tricks (spaces/tabs) to push malicious code out of default visible ranges. Detection requires inspecting package contents (build/.targets, tools scripts and embedded resources) and validating package publishers; indicators such as the listed package names, versions and SHA1 hashes can be used to identify and block known malicious releases.
Read more: https://www.reversinglabs.com/blog/iamreboot-malicious-nuget-packages-exploit-msbuild-loophole