ReversingLabs has identified connections between a malicious campaign that was recently discovered and reported by the firm Phylum and several hundred malicious packages published to the NuGet package manager since the beginning of August. The latest discoveries are evidence of what seems to be an ongoing and coordinated campaign.
Furthermore, ReversingLabs research shows how malicious actors are continuously improving their techniques and responding to the disruption of their campaigns. Specifically, threat actors have moved from simple downloaders executing inside install scripts to a more refined approach that exploits NuGet’s MSBuild integrations feature.
An IAmRoot reboot? Revisiting a hidden code execution technique
On October 15, three packages exploiting a previously unseen execution technique were published to the NuGet repository: ZendeskApi.Client.V2, Betalgo.Open.AI, and Forge.Open.AI. These are typosquatting on popular Nuget packages named ZendeskApi.Client, Betalgo.OpenAI and Forge.OpenAI.
Typosquatting attacks are common, as we have reported. But these packages employed an unusual code execution technique that is worth mentioning. Most of the malware published to the NuGet repository places malicious code inside the initialization and post installation PowerShell scripts. These packages use a different approach, with the malicious functionality placed inside the <packageID>.targets file in the “build” directory.
The first NuGet package we detected using this technique for malicious purposes was version 6.5.3 of Pathoschild.Stardew.Mod.Build.Config package. Versions 6.5.1 and 6.5.2 of this package contained malicious functionality in initialization PowerShell scripts, but version 6.5.3 didn’t include them. Instead, the malicious functionality was placed inside the <packageID>.targets file in the “build” directory.
Figure 1: Malicious content inside the Pathoschild.Stardew.Mod.Build.Config.targets file
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. When run, it downloads an executable from a remote location and executes it in a new process. Since we haven’t previously seen malware with the malicious functionality observed in the .targets files, we did a bit of research, which led to some interesting discoveries.
First, the string artifact in the first line of the file, “IAmRootDemo” led us to the root of this execution technique. Several years ago, in 2019, the IAmRoot package was published by C. Augusto Proiete. The purpose of the package: “To demonstrate that any NuGet package can run arbitrary code on your machine.”
IAmRoot uses MSBuild integrations, which were added in NuGet v2.5 to improve the support for native projects, to achieve execution. How does it function? As described in the NuGet release notes: “When NuGet installs a package with \build files, it will add an MSBuild <Import> element in the project file pointing to the .targets and .props files.”
The sneaky part is that MSBuild files can include inline tasks, which can contain executable code. Imagine you are developing package A and you want your package to use package B. Package B contains a .targets file with an inline task containing executable code. When you add package B to your package A, the content of .targets file from package B gets imported into the project file of package A. From that moment on, every time package A is built, inline tasks from the imported .targets file will get executed. 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. 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.
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.
Figure 2: Utilizing MSBuild integrations to execute malicious code in NuGet packages
All in the (malware) family
The three previously mentioned packages — ZendeskApi.Client.V2, Betalgo.Open.AI, Forge.Open.AI — are clearly part of the same ongoing campaign, started in August, and are very similar to the Pathoschild.Stardew.Mod.Build.Config package. They contain almost identical functionality in the .targets file (Figure 1), except that the obfuscated stage 2 payload is in the latest case downloaded from a GitHub repository and not from an attacker controlled IP address.
The malware authors also tried to make the malicious code harder to spot by using spaces and tabs to move it outside of the content visible within the default screen width. (ReversingLabs researcher Lucija Valentić observed a similar technique used in campaign on the Python Package Index (PyPI) in February.) They also inflated the download count numbers to make the package look more trustworthy, as evidenced by the vast majority of package downloads being attributed to an “unknown” client, versus some version of the NuGet client.
The malicious NuGet packages were detected by ReversingLabs within less than 24 hours of being published and were reported to the NuGet security team and removed shortly after preventing a more severe impact of the campaign. This discovery has been linked to a previous campaign which utilized init.ps1 scripts to achieve code execution.
One week later on Sunday, October 22, we observed malicious actors preparing to publish another set of malicious NuGet packages. Threat actors created several packages and published two versions that contained benign code in the .targets file that writes a simple message to the console.
Figure 3: Version stats for one of the malicious packages
The next day, downloads for the package were pumped up to make package statistics look more trustworthy. Then, on October 24, the malicious versions of the packages were finally published. They contained the same downloader functionality, fetching the stage 2 malware payload from the newly created, throwaway GitHub repository. This time, the Stage 2 malware was a .NET executable which executes an obfuscated command line embedded as a resource.
Figure 4: Newly created, throwaway GitHub account
The packages published in this group imitated popular packages published by the following NuGet publishers: CDataSoftware, ServiceTitan, cloudextend-oss and syntellect. These typosquatting attacks were very convincing, using the same icons for packages and package names that differed by only a single dot. Such decoy packages would be difficult for a developer to identify without close inspection of the packages to spot these subtle differences (Figure 5).
Figure 5: Search results displaying an legitimate (top) and malicious, typo-squatted package
This is more proof that the threat actor behind this campaign is being careful and paying attention to details, and is determined to keep this malicious campaign alive and active.
Round up the usual code execution techniques!
As noted, the latest packages have strong links to a campaign described in a recent research blog post published by Phylum on October 6. That research described a typosquatting campaign delivering SeroXen RAT. In that campaign, the malware used a well-known execution technique that was also observed in a campaign distributing the Impala Stealer and reported by JFrog in March, 2023.
In both cases downloader functionality was placed into PowerShell scripts located inside the “tools” directory of the NuGet package. This included init.ps1, install.ps1 and uninstall.ps1 scripts, which are run on certain events including installation and uninstallation of a package, depending on the version of the Visual Studio. These scripts are deprecated by newer versions of the NuGet format, but Visual Studio still executes the content inside the init.ps1 script upon installation of a NuGet package, regardless of whether it is specified in the .nuspec file.
This autorun mechanism is quite a popular technique for code execution in NuGet packages and the packages Phylum reported are a part of a broader, previously unreported campaign started in August 2023. This campaign was quite noisy, and included more than 700 packages which were quickly detected and removed from the NuGet repository. They very likely didn’t have a big impact. The packages detected by Phylum weren’t very sophisticated and contained only the basic files required to satisfy NuGet requirements. Even the name of the .nuspec file didn’t conform with NuGet package ID naming convention, making it easier to spot.
Figure 6: Content of the malicious Nughettt.TestPO package published in August
The malicious functionality was fairly simple. It was located in the tools/init.ps1 script and downloaded a stage 2 payload from a remote location and executed it afterwards.
Figure 7: Content of the init.ps1 script from one of the detected packages
The first package published as a part of that campaign was Nughettt.TestPO, published on August 1st. There were several connections between the 700 packages published in August and the packages from Phylum’s report. The first one is the comment “# IGBOAT Crew” detected in the code from both groups of packages. More proof of this was found in the fafagewg.nuspec file, which is located in the Nughettt.TestPO package and also in some of the packages published by the author Disti, mentioned in Phylum’s report.
Additionally, a package named Pathoschild.Stardew.Mod.BuildConfig, almost identically named as the Pathoschild.Stardew.Mod.Build.Config (different in only one ‘.’) package from Phylum’s report, contained the same payload as the initial Nughettt.TestPO package, further proving that all of these packages are part of the same campaign.
Previous research reports from ReversingLabs have warned about security threats in the npm, PyPI and RubyGEMS ecosystems. 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.
Specifically, this research report describes an ongoing campaign which has been targeting the NuGet repository since August 2023. The threat actors behind it are tenacious in their desire to plant malware into the NuGet repository, and to continuously publish new malicious packages. As soon as the previous packages are removed from the repository, ReversingLabs detected newly published packages on a daily basis.
The new malware samples ReversingLabs detected suggest that the malicious actors responsible for this campaign are adopting a documented but uncommon technique that exploits NuGet’s MSBuild integrations feature in order to plant malicious code on their victims. As always, developers need to remain vigilant of the threats lurking in the open source ecosystem.
What’s needed is deep visibility inside software packages, to distinguish malicious functions from legitimate ones. This can be challenging with legacy application security testing tools, and demands specialized skills and knowledge that many organizations lack. Modern tools like ReversingLabs Software Supply Chain Security can bridge the gaps, and help development and application security teams protect their supply chain from compromise.
Indicators of Compromise (IOCs)
Indicators of Compromise (IoCs) refer to forensic artifacts or evidence related to a security breach or unauthorized activity on a computer network or system. IOCs play a crucial role in cybersecurity investigations and cyber incident response efforts, helping analysts and cybersecurity professionals identify and detect potential security incidents.
The following IOCs were collected as part of ReversingLabs investigation of this software supply chain campaign.