NPM上发现恶意软件,通过反向shell感染本地包。
Malware found on NPM infecting local package with reverse shell

原始链接: https://www.reversinglabs.com/blog/malicious-npm-patch-delivers-reverse-shell

近期一次npm恶意软件活动利用复杂技术入侵系统,凸显了软件供应链中持续存在的风险。“ethers-provider2”和“ethers-providerz”等软件包携带有隐藏的有效负载,这些有效负载会“修补”本地安装的合法“ethers”和“@ethersproject/providers”软件包,注入恶意代码。此修改后的代码会下载更多恶意软件,最终导致与攻击者服务器的反向shell连接。 攻击者采用了巧妙的规避策略,确保删除最初的恶意软件包并不一定能消除入侵。被修补的“ethers”软件包将仍然被感染,如果恶意软件包存在,重新安装“ethers”将触发再次感染。ReversingLabs (RL) 检测到这些软件包,并开发了YARA规则来识别被修补的“ethers”安装。 虽然2023年到2024年间npm恶意软件实例有所减少,但这起事件表明,针对开源存储库的威胁行为者的复杂性和持久性。这突显了需要加强警惕和安全措施以防范供应链攻击。

最近Hacker News上的一篇帖子讨论了在一个NPM包中发现的恶意软件,该恶意软件创建了一个反向shell,突出了开源代码库安全性的担忧。用户们就可能的解决方案展开了辩论,包括谷歌的“安全可靠的”开源代码库以及对更强大的安全措施的需求。 一些评论者指出,大多数包存储库(Go、Rust、Swift、Ruby、Python)缺乏审查机制,这与Java的Maven/Sonatype的自动化检查和OCaml的opam审查流程形成了对比。 讨论还围绕着`npx`和`postinstall`脚本相关的风险展开,这些脚本允许未经请求的网络和文件系统访问。提出的解决方案包括包装二进制执行以需要用户授权。一些用户建议使用人工智能来扫描恶意软件包,而另一些用户则通过建议添加诸如“区块链”之类的流行词来讽刺这个想法。总体情绪反映了人们对依赖未经检查的开源包所固有的安全漏洞日益增长的不安。

原文

Malicious-npm-patch-delivers-reverse-shellUnlike some other public repositories, the npm package repository is never really quiet. And, while there has been some decline in malware numbers between 2023 and 2024, this year's numbers don’t seem to continue that downward trend. Still, while RL has detected some interesting npm malware so far this year, none of it warranted a detailed writeup.

Then March rolled around, and two very interesting packages were published on npm: ethers-provider2 and ethers-providerz. These were simple downloaders whose malicious payload was cleverly hidden, with a second stage that “patches” the legitimate npm package ethers, installed locally, with a new file containing the malicious payload. That patched file ultimately serves a reverse shell.  

This approach reveals a high level of sophistication on the threat actor’s part that deserves some further analysis and exploration. 

ethers-provider2 delivers the malware

The package ethers-provider2 was still available on npm at the time of publication. The package mirrors another, legitimate and widely-used npm package, ssh2, which has more than 350 million downloads and more than 1,600 dependent applications. The ethers-provider2 package contains the ssh2 source code, adding some malicious elements to it. So the whole package functions exactly how the ssh2 package would — with something extra.

The package was easily detected by RL's Spectra platform, with telltale signs it contained malicious code. First, the file install.js had been modified to include a malicious payload downloading second stage malware from the domain hxxp[:]//5[.]199[.]166[.]1[:]31337/install. Upon installation, the install script install.js is executed and a second stage is downloaded to a temporary file and then executed. Immediately after that, the temporary file is deleted, removing any indication that anything happened, which was another sign the package is malicious, since this usually doesn’t happen in legitimate packages. 

As we looked at the second stage malware, things got really interesting. The malware goes into an infinite loop that checks if the legitimate npm package ethers is installed locally. If it is installed, or once it is installed, the second-stage malware springs into action: replacing one of its files, provider-jsonrpc.js, with a file that looks- and functions the same, but includes additional, malicious code that downloads the third-stage malware from hxxp[:]//5[.]199[.]166[.]1[:]31337/config and executes it.

ReversingLabs

Figure 1: ethers-provider2’s second stage

The second-stage malware also creates a file, loader.js, which writes code with the same functionality as the malicious code used to “patch” the ethers’ file, and then runs it.

The third stage serves a reverse shell connecting to the threat actor’s server, which is accessed using an ssh client from ethers-provider2. This client functions in the same way as a client from a legitimate ssh2 package would, but it is modified to receive additional messages. That means that the connection opened with this client turns into a reverse shell once it receives a custom message from the server. This is true even if the ethers-provider2 package is removed from a compromised system: the client will still be used under certain circumstances, providing a degree of persistence for the attackers. 

ReversingLabs

Figure 2: Reverse shell opened towards threat actors’ server

Discussion

While not as common as infostealers on the npm platform, downloaders are far from uncommon and are frequently encountered. However, this downloader is notable because of the exceptional strategies employed by the attackers to hide the malicious payload it delivered. These evasive techniques were more thorough and effective than we have observed in npm-based downloaders before. 

Specifically, once the malicious payload, ethers-provider2, was delivered, its removal wouldn’t necessarily remove its malicious functionality. Instead, it would remain hidden in another location. And if the package ethers-provider2 was present when the ethers package was removed and installed again, it would patch it again in the same way described previously. 

It is also important to mention once again that the malicious code was only put inside the locally installed npm package ethers, and that the official npm package ethers was not compromised in any way. 

I am (not) throwin’ away my shot

The other package belonging to the same campaign, ethers-providerz had only three versions, and the last two were very similar to ethers-provider2; whereas the first one 1.16.0 looked more like a test version, with some parts that didn't work as the threat actor probably intended.

The malicious payload was located in the install script install.js. It tries to “patch” several files of a legitimate locally installed npm package @ethersproject/providers in the same way ethers’ file provider-jsonrpc.js was patched. 

Which npm package was targeted for patching is speculative at this point, because the path to each file was written incorrectly, with the threat actor defining the scope, but not providing the name of the intended package.

ReversingLabs

Figure 3: Malicious payload inside install.js script

The RL research team also observed the malicious payload creating a malicious file, loader.js, in the folder node_modules, and executing it. The node_modules folder is where npm packages are stored by default once they are installed. The file loader.js downloads the second stage from hxxp[:]//5[.]199[.]166[.]1[:]31337/config.

What's interesting about this is that there is a legitimate npm package called loader.js with more than 24 million downloads and 5,200 dependent applications.This suggests that, as with ssh2,  the threat actor was looking to “patch” a common, legitimate, and locally-installed npm package with a nearly identical version containing malicious code.

RL YARA rule helps detect ethers

Detection of the malicious packages ethers-provider2 and ethers-providerz was the easy part. They had very low download counts and contained non-obfuscated malicious code downloading the second stage inside the install script. RL’s Spectra platform finds obfuscated or non-obfuscated — and clearly malicious code — lurking in install scripts by identifying behaviors and characteristics when scanning both open- source and commercial, closed-source binaries.  

Despite the low download numbers, these packages are powerful and malicious. If their mission is successful, they will corrupt the locally installed package ethers and maintain persistence on compromised systems even if that package is removed.

As of the time of publication, the package ethers-providerz was removed from npm, probably by the package's author because it has no security holding package. Package ethers-provider2 is still on npm, but has been reported to the npm maintainers.

To address the risks posed by these packages, RL developed a simple YARA rule to help in detecting whether locally installed package ethers was “patched” or not.

ReversingLabs

Figure 4: Malicious part of the “patched” file

YARA Rule

rule npm_Downloader_InjectedMaliciousCode
{
    meta:

        author              = "ReversingLabs"

        source              = "ReversingLabs"
        category            = "MALWARE"
        description         = "Yara rule that detects if there is a malicious payload injected in legitimate locally installed npm package ethers."

    strings:

        $decode_payload_url = "atob(atob(\"YUhSMGNEb3ZMelV1TVRrNUxqRTJOaTR4T2pNeE16TTNMMk52Ym1acFp3PT0=\"))"
        $fetch_payload = "fetch("               
        $execute_payload = "eval("

    condition:
        all of them
}

Even more packages?

After this research was done, new packages were found that appear to be connected to this campaign: reproduction-hardhat and @theoretical123/providers. The former was a simple reverse shell that would connect to the IP address 5[.]199[.]166[.]1, and the latter was a package downloading a second stage from hxxp[:]//5[.]199[.]166[.]1[:]31337/config and impersonating a legitimate npm package @ethersproject/providers. Both have been removed from npm.

Conclusion

As RL noted in its 2025 Software Supply Chain Security Report, the scope of software supply chain risks is growing for both software producers and end-user organizations. While there was a drop in instances of malware discovered on open-source repositories like npm and PyPI in 2024, threat actors have not lost interest in promoting malicious packages to open-source developers. 

This latest campaign is evidence that the risk of downloading malware and compromising development environments and networks remains high, while novel ways of serving malicious payloads are emerging.

The RL research team has already seen malicious packages serving malicious payloads that was in plain sight, obfuscated or cleverly hidden. Sometimes these packages are malicious by design. Other times, popular legitimate npm packages were hijacked and injected with malicious code. In these cases, there is usually a combination of approaches: the designed-malicious npm package injects a malicious payload into a legitimate and locally installed npm package, making it serve as a reverse shell. This approach makes it easier for the threat actor by reducing hurdles to hijacking a malicious open-source package. 

What is even more ominous with this current threat: Even if the malicious package ethers-provider2 is removed, the threat actors made sure their malicious functionality would persist. This highlights the importance of being alert to supply chain threats and attacks, since there are many malicious packages lurking on npm, serving malware in novel and not-so-novel ways.

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 RL's investigation of this malicious software supply chain campaign.

Second-stage payload

SHA1
hxxp[:]//5[.]199[.]166[.]1[:]31337/install

Third-stage payload

SHA1
hxxp[:]//5[.]199[.]166[.]1[:]31337/config

 

联系我们 contact @ memedata.com