Despite efforts taken in recent years to proactively monitor public software repositories for malicious code, packages that bundle malware continue to routinely pop up in such places.
Researchers recently identified two legitimate looking packages that remained undetected for over two months and deployed an open-source information stealing trojan called TurkoRat.
Effective use of typosquatting on malicious npm packages
Attackers attempt to trick users into downloading malicious packages in several ways, and typosquatting is one of the most popular because it doesn't take a lot of effort. This technique involves copying a legitimate package, adding malicious code to it and publishing it with a different name that's a variation of the original in the hope that users will find it when searching for the real package.
This was the case with a package called nodejs-encrypt-agent that recently caught the attention of researchers from software supply chain security firm ReversingLabs because it displayed a combination of suspicious characteristics and behaviors. First, the name of the package in the npm registry was different from that declared in its readme.md file: agent-base. Second, the first version of the package uploaded to the registry was 6.0.2, which is unusual because new packages typically start out with a low version like 1.0 or even lower.
When the researchers searched for agent-base it all made sense. This is a legitimate package whose most popular version on the registry is 6.0.2 with over 20 million downloads. A code comparison revealed that nodejs-encrypt-agent was just a copy of agent-base's code base with a few modifications. In fact, the rogue package even contained a link to agent-base's GitHub page, possibly to appear more legitimate.
"In the course of analysing millions of suspicious packages, the ReversingLabs team has identified a number of combinations of behaviors that, when seen together, are highly indicative of malicious activity," the researchers said in a report. "For example, open-source packages that contain hard-coded IP addresses in their code, while also executing commands and writing data to files, in our experience, usually turn out to be malicious. It is true: None of those capabilities, individually, are malicious. When seen in combination, however, they’re usually supporting malicious functionality."
The modification attackers made to the agent-base code was to execute a portable executable (PE) file delivered with the new packages immediately after the package was downloaded and installed on a system. An automated analysis of this file identified the ability to write and delete files from Windows system directories, execute system commands, modify the system's Domain Name System (DNS) settings -- all of which looked suspicious.
"As it turns out, this particular version of the TurkoRat malware uses the npm package pkg to bundle all the necessary files into a single package executable," the researchers said. "All the files reside inside a virtual file system, or snapshot, to which the packaged application has access during runtime."
According to the TurkoRat project on Discord, the malware is capable of stealing authentication and session tokens for Discord and Telegram; passwords, cookies, autofill and history from all major browsers; and a large number of crypto wallets. It is also capable of taking screenshots. All the collected information can be sent back to an attacker configured webhook URL.
Malware hiding in dependency chains
After finding nodejs-encrypt-agent, the researchers set out to search for similar packages and they soon found another called nodejs-cookie-proxy-agent that listed nodejs-encrypt-agent as a dependency. This second package was a rogue copy of a legitimate package called node-cookie-proxy-agent.
This time the name similarity between the rogue and legitimate packages is much higher -- node vs nodejs as suffix -- making it a much more effective typosquatting attempt. In fact, it suggests this package was probably intended as the first link in the attack chain since it doesn't bundle any malicious code directly. Instead, it pulls in nodejs-encrypt-agent as a dependency, which then deploys TurkoRat.
In fact, earlier versions of the nodejs-cookie-proxy-agent package pulled in a different dependency called axios-proxy that was flagged as a malicious package in the past and was removed by the npm maintainers. It seems that nodejs-cookie-proxy-agent was missed at the time and attackers simply switched dependencies to a new malicious package they created and uploaded.
"The nodejs-encrypt-agent was downloaded about 500 times during its two months of availability," the ReversingLabs researchers said. "The nodejs-cookie-proxy-agent was downloaded fewer than 700 times. Still, the malicious packages were almost certainly responsible for the malicious TurkoRat being run on an unknown number of developer machines. The longer-term impact of that compromise is difficult to measure."
Attacks through malicious software components can have wide ranging implications because the main consumers of such packages are developers. A compromised developer machine can give attackers access to the software development environment and infrastructure of the organisation the developer works for. This in turn can lead to another software supply chain attack down the line. The security industry has already documented cases of cascading software supply chain attacks.