Malicious package campaign on NuGet abuses MSBuild integrations

Attackers are constantly coming up with new ways to deploy rogue packages on public registries for different programming languages with the goal of executing malware code when those packages are imported and used in projects. The latest example is an attack campaign recently detected on NuGet Gallery, the repository for .NET packages, in which attackers use the inline tasks feature of the MSBuild code building tool to execute malicious code.

“Based on our research, this is the first known example of malware published to the NuGet repository exploiting this inline tasks feature to execute malware,” researchers from security firm ReversingLabs said in a report. “There has been an ongoing discussion about the security implications of such mechanisms in NuGet’s GitHub repository, but the issue hasn’t been resolved. We’re now dealing with the consequences of that.”

A months-long typosquatting campaign

In early October, researchers from a software supply chain security firm called Phylum discovered six malicious packages on NuGet Gallery that were uploaded by the same user and were deploying a remote access trojan called SeroXen RAT. The packages had names that were variations of existing popular packages — a technique name typosquatting — and had their download count artificially inflated by bots to appear more legitimate.

According to ReversingLabs, the packages detected by Phylum were likely part of a larger coordinated campaign on NuGet Gallery that started in August and resulted in several hundred malicious packages being uploaded to the repository over the last few months.

During the campaign, the attackers changed tactics several times when it came to hiding their malicious code inside packages and how they achieved code execution. The packages found by Phylum in early October used several layers of obfuscation for the malicious code and hid it in PowerShell scripts called tools/init.ps1 or tools/install.ps1 inside the packages, which the NuGet package manager will look for and execute when a package is installed.

For good measure, they also included a malicious tools/uninstall.ps1 file, which is executed when a package is uninstalled. The purpose of these scripts and mechanisms is to allow developers to perform some initial set-up tasks and cleanup jobs when a package is installed or uninstalled.

After Phylum’s report the attackers pivoted again and shifted to another NuGet code execution technique that had been known for a while but hadn’t been seen in the wild: MSBuild inline tasks. This technique was demonstrated in 2019 by a developer named C. Augusto Proiete who created a proof-of-concept NuGet package called IAmRoot.

In fact, Proiete created his package after Microsoft decided to drop support for the install.ps1 and uninstall.ps1 PowerShell scripts in NuGet version 3 without providing an alternative. NuGet 2.5 added better integration with MSBuild to support configuration options that don’t exist natively in NuGet.

“To address NuGet’s configuration limitations, we are relying heavily on MSBuild properties and targets for native packages,” the NuGet developers said at the time. “These MSBuild properties and targets do the heavy lifting of providing references at build time, based on your project’s configuration. To make MSBuild integration better, NuGet has created a new convention for automatically importing MSBuild properties and targets from a NuGet package. Alongside the existing content, lib, and tools folders, NuGet now recognizes a new top-level folder: build. Within the build folder, you can provide a ‘.props’ file and/or a ‘.targets’ file that will be automatically imported into the project.”

The issue is that MSBuild supports a feature called inline tasks that allows the build configuration files to create tasks that will execute code defined through code elements or located somewhere inside the project, leading to arbitrary code execution.

The IAmRoot reboot

Researchers from ReversingLabs found three packages that abused the build .targets file and were uploaded to NuGet Gallery on October 15. The packages were called ZendeskApi.Client.V2, Betalgo.Open.AI, and Forge.Open.AI, and all were clearly tied to the ongoing campaign that began in August.

“The code encapsulated inside the <Code> property of this XML file is almost identical to the functionality present in the PowerShell scripts from the earlier two versions of the package,” the researchers said. “When run, it downloads an executable from a remote location and executes it in a new process.”

After the packages were reported to the NuGet team and were removed from the repository, the attackers created new ones on October 22 that typosquatted legitimate packages from existing developers CDataSoftware, ServiceTitan, cloudextend-oss, and syntellect. The rogue packages were very hard to differentiate from the legitimate ones, their names differing by only one dot and using the same icons and description. The same previously observed technique of artificially inflating download counts was also employed. The malicious payload for this new round of packages was a .NET executable hosted in a newly created GitHub repository and which executed an obfuscated command line embedded as a resource.

This technique is likely to become more popular now that one group of attackers has started using it and can even be used with stacked dependencies, making it harder to detect. For example, package A can be clean but list package B as a dependency and package B can have a.targets file with malicious inline tasks that would be imported and executed. Similar attacks through multiple layers of dependencies have been observed in the past with other package managers and registries.

“Previous research reports from ReversingLabs have warned about security threats in the npm, PyPI, and RubyGEMS ecosystems,” the researchers said. “This newest finding adds the NuGet package repository to that list and proves that NuGet is equally exposed to malicious activities conducted by threat actors.”

Cyberattacks, DevSecOps, Malware, Supply Chain