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.”