AI生成|Shai-Hulud(TeamPCP)源码分析

admin 2026-05-18 06:27:40 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: Shai-Hulud是由TeamPCP开发的严重级供应链攻击框架,专门针对CI/CD管道(如GitHubActions和npm)进行植入。该工具具备多层规避检测机制(如俄语系统检测、进程守护)、系统化凭证收集能力(覆盖AWS/K8s/Vault等200+敏感路径),并通过加密外传至C2或GitHub私有仓库。内置横向移动模块可劫持GitHubtoken进行仓库渗透,且包含破坏性deadmanswitch机制(如触发rm-rf清除数据)。攻击者需替换C2和密钥后部署,建议企业严格审查第三方依赖并监控异常CI行为。 综合评分: 85 文章分类: 恶意软件,供应链安全,漏洞分析,威胁情报,安全工具


cover_image

AI 生成 | Shai-Hulud (TeamPCP) 源码分析

原创

GLM-5.1 GLM-5.1

赛博生存指南

2026年5月15日 21:22 浙江

在小说阅读器读本章

去阅读

生成日期:2026-05-15 分析对象:Shai-Hulud Open Source Release 威胁分类:供应链攻击 / 凭证窃取框架 风险等级:严重 (Critical) 官网:hxxps://supplychain.breached.st


1. 概述

Shai-Hulud 是一个高度复杂的供应链攻击与凭证窃取框架,由威胁行为者 “TeamPCP” 开发并公开源码。TeamPCP向BreachForums 社区开源 Shai Hulud。并宣布可以观测到的最大供应链攻击的运营商将从@diencracked获得1000美元XMR。

该工具设计为植入 CI/CD 管道(特别是 GitHub Actions 和 npm 发布流程),执行大规模凭证窃取、横向移动和数据外传。README 中的 “Change keys and C2 as needed” 直接表明这是一个供攻击者定制部署的武器化工具。包名伪装为 voicefromtheouterworld,构建产物使用 javascript-obfuscator 进行深度混淆。


2. 攻击链 (Kill Chain)

植入 (Injection)
  ↓
预检规避 (Pre-flight Evasion)
  ↓
快速收集 (Quick Collection) — 本地文件、环境变量、Shell 凭证
  ↓
横向扩展 (Lateral Movement) — AWS / K8s / Vault / GitHub Actions
  ↓
加密外传 (Encrypted Exfiltration) — C2 域名或 GitHub 私有仓库
  ↓
持久化/破坏 (Persistence / Sabotage) — Deadman Switch / OIDC 伪造

3. 核心组件分析

3.1 预检规避 (Anti-Detection)

相关文件: src/utils/config.tssrc/utils/daemon.tssrc/utils/lock.tssrc/index.ts

| 规避手段 | 实现细节 | | — | — | | 俄语系统规避 | isSystemRussian() 检测 locale 是否为 ru,若是则立即 process.exit(0) — 规避特定地区 | | 非 CI 守护进程化 | daemonize() 在非 CI 环境中 spawn 子进程并 unref(),脱离终端 | | 进程锁 | acquireLock() 使用文件锁防止多实例运行暴露异常 | | 信号屏蔽 | 捕获 SIGINT/SIGTERM 为空操作,阻止 Ctrl+C 终止 | | 目标仓库检查 | checkTargetRepo() 检查 GITHUB_REPOSITORY 是否为 opensearch-js,且 workflow 为 release-drafter.yml | | 字符串混淆 | scramble() 函数 + env-scramble.ts 编译期将所有敏感字符串编码 |

关键代码 (src/index.ts:73-77):

if (isSystemRussian()) {
  logUtil.log("Exiting as russian language detected!");
  process.exit(0);
}

关键代码 (src/utils/daemon.ts):

const child = spawn(process.execPath, process.argv.slice(1), {
  detached: true,
  stdio: "ignore",
  env: { ...process.env, __DAEMONIZED: "1" },
});
child.unref();

3.2 凭证收集 (Providers / 数据窃取层)

3.2.1 FileSystemService — 本地文件系统扫描器

相关文件: src/providers/filesystem/filesystem.ts

扫描 200+ 个敏感文件路径,覆盖三大操作系统:

主要目标类别:

| 类别 | 示例路径 | | — | — | | SSH 密钥 | ~/.ssh/id_rsa~/.ssh/id_ed25519~/.ssh/config | | AWS 凭证 | ~/.aws/credentials~/.aws/config | | GCP 凭证 | ~/.config/gcloud/credentials.dbapplication_default_credentials.json | | Docker 凭证 | ~/.docker/config.json | | Kubernetes | ~/.kube/config/var/run/secrets/kubernetes.io/serviceaccount/token | | 加密货币钱包 | ~/.bitcoin/wallet.dat~/.ethereum/keystore/*~/.monero/*~/.electrum/wallets/* | | VPN 配置 | NordVPN, ProtonVPN, CyberGhost, OpenVPN 配置文件 | | 环境变量文件 | .env.env.local.env.production | | Git 凭证 | .git-credentials~/.gitconfig.git/config | | Terraform | ~/.terraform.d/credentials.tfrc.json | | 浏览器/通讯数据 | Discord/Slack/Signal/Telegram 本地存储 | | CI/CD 工具 | ~/.claude.json~/.claude/mcp.json~/.kiro/settings/mcp.json | | 数据库配置 | **/database.yml**/wp-config.php |

同时在文件内容中用正则匹配提取 gh[op]_* GitHub token 和 npm_* npm token。

3.2.2 ShellService — Shell 环境窃取

相关文件: src/providers/devtool/devtool.ts

  • • 执行 gh auth token 获取当前 GitHub CLI token
  • • 导出整个 process.env — 一次性获取所有环境变量
results["environment"] = process.env;  // 完整环境变量泄露

3.2.3 GitHubRunner — 运行器元数据

相关文件: src/providers/ghrunner/runner.ts

收集 GitHub Actions 运行器环境信息。

3.2.4 AwsSecretsManagerService — AWS Secrets Manager 窃取

相关文件: src/providers/aws/secretsManager.ts

  • • 自动解析 AWS 默认凭证链 (resolveDefaultCredentials)
  • • 遍历 18 个 AWS 默认启用区域
  • • 枚举每个区域的所有 Secret 并读取明文值 (GetSecretValue)
  • • 包含完整的 SigV4 签名实现 (src/providers/aws/sigv4.ts),不依赖 AWS SDK
  • • 内置权限错误分类和重试逻辑

3.2.5 AwsSsmService — AWS SSM Parameter Store 窃取

相关文件: src/providers/aws/ssm.ts

  • • 遍历 18 个区域
  • • 使用 DescribeParameters + GetParameters (含 WithDecryption: true)
  • • 解密所有 SecureString 参数
  • • 分批处理(每批 10 个),带指数退避重试

3.2.6 K8sSecretsService — Kubernetes Secrets 窃取

相关文件: src/providers/kubernetes/kubernetes.ts

  • • 自动检测集群内/集群外环境
  • • 读取 ServiceAccount token 或从 kubeconfig 提取 token
  • • 枚举所有命名空间,读取所有 Secret
  • • base64 解码所有 Secret data 值
  • • 在 Secret 内容中进行 20+ 种正则匹配(AWS/GCP/Azure key, Stripe, Slack, SSH key, DB 连接串等)

3.2.7 VaultSecretsService — HashiCorp Vault 窃取

相关文件: src/providers/vault/vault-secrets.ts

支持 4 种认证方式:

  1. 1. 环境变量 token (VAULT_TOKENVAULT_AUTH_TOKENVAULT_API_TOKEN)
  2. 2. 文件 token (~/.vault-token/vault/token 等 12 个候选路径)
  3. 3. Kubernetes Auth(使用 K8s ServiceAccount JWT)
  4. 4. AWS IAM Auth

认证后:

  • • 枚举所有 KV mount(排除 sys/ 和 auth/
  • • 遍历 KV v1 和 KV v2 存储
  • • 读取所有 secret 的完整数据

3.2.8 GitHubActionsService — GitHub 横向移动

相关文件: src/providers/actions/actions.tssrc/providers/actions/secrets.tssrc/providers/actions/pipeline.ts

  • • 使用窃取的 GitHub token,验证是否具有 workflow 权限
  • • 通过 REST API 列举用户所有仓库
  • • 枚举每个仓库的 Actions Secrets 和 Organization Secrets
  • • 通过 GraphQL API 批量操作

3.3 数据外传 (Exfiltration / Sender 层)

3.3.1 DomainSender — 主要 C2 通道

相关文件: src/sender/domain/sender.tssrc/sender/domain/domainSenderFactory.ts

  • • C2 地址https://git-tanstack.com:443/router(伪装 TanStack 域名)
  • • 预检:DNS 解析验证 + HTTP 健康检查(接受 400/404 为健康)
  • • 备用 C2 发现:通过 findValidSignedCommit() 搜索 GitHub 上 GPG 签名消息为 “thebeautifulmarchoftime ” 的 commit,提取备用域名
  • • 数据用混合加密保护(详见 3.3.3)

3.3.2 GitHubSender — 备用外传通道

相关文件: src/sender/github/githubSender.tssrc/sender/github/createRepo.ts

  • • 在受害者 GitHub 账户上创建私有仓库
  • • 通过 Contents API 分块上传窃取数据(每块最大 30MB)
  • • 将加密密钥嵌入 commit message

内置破坏机制 — Deadman Switch (src/sender/github/githubSender.ts:58-76):

private async installTokenMonitor(token: string, handler: string) {
  const proc = Bun.spawn(["bash", "-s", "--", token, handler], {
    stdin: "pipe", stdout: "pipe", stderr: "pipe",
  });
  proc.stdin.write(DEADMAN_SWITCH);
  proc.stdin.end();
}

当 includeToken 为 true 时,部署 deadman switch — 如果 token 被撤销,执行 rm -rf ~/ 清除受害者主目录。

3.3.3 加密流程

相关文件: src/sender/base.ts

原始数据 (ProviderResult[])
  ↓ JSON.stringify
  ↓ Buffer.from
  ↓ gzip 压缩
  ↓ AES-256-GCM 加密 (随机 32 字节 key + 随机 12 字节 IV)
  ↓ [IV + 密文 + authTag] → base64 (envelope)
  随机 AES key
  ↓ RSA-OAEP + SHA-256 加密 (攻击者公钥, 来自 generated/index.ts)
  ↓ base64 (key)
  → { envelope: base64, key: base64 }

只有持有 RSA 私钥的攻击者能解密。

3.4 供应链攻击 (Mutator 层)

3.4.1 ReadmeUpdater (Branch Mutator)

相关文件: src/mutator/branch/

  • • 使用窃取的 GitHub token (ghs_old / ghs_jwt 类型)
  • • 通过 GraphQL API 在目标仓库的分支上创建 commit
  • • 修改仓库内容,注入恶意代码
  • • 自动过滤 dependabot/copilot 分支,避免触发自动化检测

3.4.2 NpmClient — npm 包发布攻击

相关文件: src/mutator/npm/publish.ts

  • • 使用窃取的 npm token 发布恶意包
  • • 禁用 TLS 验证tls: { rejectUnauthorized: false }
  • • 伪装 User-Agent 为 npm/11.13.1

3.4.3 NPMOidcClient — OIDC Provenance 伪造

相关文件: src/mutator/npmoidc/provenance.ts

这是最危险的组件之一。 完整实现了 Sigstore 签名流程:

  1. 1. 构建 SLSA v1 provenance statement(in-toto 格式)
  2. 2. 通过 GitHub Actions OIDC 获取 sigstore audience token
  3. 3. 生成临时 ECDSA P-256 密钥对
  4. 4. 向 Fulcio CA 请求签名证书(proof-of-possession)
  5. 5. 创建 DSSE envelope 签名
  6. 6. 提交到 Rekor 透明日志
  7. 7. 组装 sigstore bundle v0.3

影响:恶意包可以拥有完全合法的签名证明链,绕过所有现有的供应链验证机制。

定向攻击目标:OpenSearch-JS 仓库的 release-drafter.yml workflow。


4. 混淆与构建基础设施

相关文件: scripts/obfuscate.jsscripts/env-scramble.tsscripts/strip-logs.tsscripts/build.ts

| 技术 | 作用 | | — | — | | scramble() | 编译期字符串编码,隐藏 C2 域名、API 路径、文件路径 | | env-scramble | 将 process.env.KEY 重写为 process.env[scramble("KEY")] | | javascript-obfuscator | 控制流扁平化 + base64 字符串编码 | | strip-logs | 发布版移除所有日志输出 | | 包名伪装 | voicefromtheouterworld — 与功能无关 |


5. IoC (入侵指标)

网络

| 指标 | 类型 | 说明 | | — | — | — | | git-tanstack.com | C2 域名 | 主要外传通道 | | git-tanstack.com:443/router | C2 端点 | HTTPS POST 外传加密数据 | | api.github.com | 外传通道 | 备用 — 创建私有仓库上传数据 | | GPG 签名消息 “thebeautifulmarchoftime ” | 备用 C2 发现 | 通过签名 commit 传递备用域名 |

文件系统

| 指标 | 说明 | | — | — | | __DAEMONIZED 环境变量 | 守护进程标记 | | .omc/ 或锁文件存在 | 进程锁文件 | | voicefromtheouterworld 包名 | npm 包伪装名 |

代码特征

| 指标 | 说明 | | — | — | | 函数 scramble() 声明 | 字符串解码函数 | | IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner | Deadman switch 字符串 | | thebeautifulmarchoftime (含尾部空格) | 签名 commit 搜索串 | | opensearch_init.js | 伪装脚本名 | | github:opensearch-project/opensearch-js#d446803f4c3bc... | 目标包引用 |

GitHub 活动指标

| 指标 | 说明 | | — | — | | 异常的私有仓库创建 | 外传通道创建的临时仓库 | | Commit message 包含 base64 编码 token | Deadman switch 关联的 commit | | results/*.json  文件上传 | 窃取数据的分块文件 |


6. 攻击向量总结

| 攻击向量 | 目标 | 影响 | | — | — | — | | npm 供应链投毒 | npm 生态系统用户 | 后门包 + 伪造 SLSA provenance | | GitHub Actions 后门 | CI/CD 管道 | 窃取仓库 secrets、OIDC token | | AWS 凭证窃取 | AWS 用户 | 读取 18 个区域的 Secrets Manager + SSM | | Kubernetes 窃取 | K8s 集群 | 读取所有命名空间 Secrets (base64 解码) | | Vault 窃取 | Vault 用户 | 读取所有 KV v1/v2 存储 | | 本地文件扫描 | 开发者机器 | SSH 密钥、钱包、VPN、浏览器数据 (200+ 路径) | | 横向移动 | GitHub 组织 | 用窃取的 token 扩大到所有仓库 | | 破坏性打击 | 受害者系统 | Deadman switch: rm -rf ~/ | | OIDC 伪造 | Sigstore 生态 | 为恶意包生成合法签名证明 |


7. 检测与防御建议

7.1 网络层

  • • DNS 监控:检测对 git-tanstack.com 的查询
  • • HTTPS 检测:检测到 git-tanstack.com:443/router 的 POST 请求
  • • TLS 检测:识别禁用证书验证的出站连接 (rejectUnauthorized: false)

7.2 终端层

  • • 进程监控:检测带有 __DAEMONIZED 环境变量的 spawn 进程
  • • 文件访问监控:检测对 200+ 热点路径的批量读取
  • • Shell 监控:检测 gh auth token 的非预期调用

7.3 CI/CD 层

  • • 最小权限原则:限制 GitHub Actions OIDC token 的 audience 范围
  • • Workflow 审计:检查构建步骤中是否引入了不明依赖
  • • 依赖锁定:使用 lockfile 并验证包完整性

7.4 供应链层

  • • npm 审计:检查包是否包含 scramble 函数或可疑的网络连接
  • • Provenance 验证增强:不仅要验证签名有效性,还要验证构建环境的可信度
  • • Sigstore 监控:关注 Rekor 日志中异常的 provenance bundle

7.5 事件响应

如果检测到该工具在您的环境中运行:

  1. 1. 立即隔离 受影响的 CI/CD runner 和容器
  2. 2. 轮换所有凭证:GitHub token, AWS credentials, K8s secrets, Vault tokens, SSH keys, npm tokens
  3. 3. 审查 GitHub 账户:检查是否有异常的私有仓库创建
  4. 4. 审计 npm 发布历史:检查是否有未授权的包版本发布
  5. 5. 备份后清理:在确认数据安全前,不要执行 rm -rf 之类的操作

8. 技术评估

8.1 代码质量

  • • 架构清晰,模块化程度高(Provider/Sender/Collector/Dispatcher 模式)
  • • 错误处理完善,具有重试、退避、容错机制
  • • TypeScript 编写,类型定义完整
  • • 使用混合加密方案,符合密码学最佳实践

8.2 武器化程度

  • • 多层级规避:地区检测、CI 检测、守护进程、信号屏蔽
  • • 弹性架构:多通道外传(C2 → GitHub repo → 备用 C2)
  • • 自保护:Deadman switch 防止 token 撤销
  • • 供应链深度伪造:OIDC + Sigstore + SLSA provenance 全链路伪造

8.3 威胁评估

该工具展现了高级持续性威胁 (APT) 级别的能力:

  • • 跨平台支持(Linux/macOS/Windows)
  • • 覆盖所有主流云服务提供商和密钥管理系统
  • • OIDC provenance 伪造能力对当前供应链安全体系构成根本性挑战
  • • 其公开源码发布意味着其他威胁行为者可以复制和改进这些技术

附录 A: 文件结构映射

src/
├── index.ts                          # 主入口,编排所有组件
├── generated/index.ts                # RSA 公钥、verify key、deadman switch 脚本
├── collector/collector.ts            # 数据收集缓冲和分发
├── dispatcher/dispatcher.ts          # 多通道外传调度(含 fallback)
├── sender/
│   ├── base.ts                       # 加密 envelope 构建 (RSA-OAEP + AES-256-GCM)
│   ├── domain/sender.ts              # C2 域名外传通道
│   ├── domain/domainSenderFactory.ts # 含备用 C2 发现逻辑
│   ├── github/githubSender.ts        # GitHub 私有仓库外传 + deadman switch
│   └── github/createRepo.ts          # 创建私有仓库
├── providers/
│   ├── filesystem/filesystem.ts      # 200+ 敏感文件扫描
│   ├── devtool/devtool.ts            # Shell 环境窃取
│   ├── ghrunner/runner.ts            # GitHub Actions runner 元数据
│   ├── aws/secretsManager.ts         # AWS Secrets Manager 窃取
│   ├── aws/ssm.ts                    # AWS SSM Parameter Store 窃取
│   ├── aws/credentials.ts            # AWS 凭证链解析
│   ├── aws/sigv4.ts                  # SigV4 签名实现
│   ├── kubernetes/kubernetes.ts      # K8s Secrets 窃取
│   ├── vault/vault-secrets.ts        # HashiCorp Vault 窃取
│   └── actions/actions.ts            # GitHub Actions 横向移动
├── mutator/
│   ├── branch/                       # Git 分支操作(代码注入)
│   ├── npm/publish.ts                # 恶意 npm 包发布
│   └── npmoidc/provenance.ts         # SLSA/Sigstore provenance 伪造
├── github_utils/
│   ├── fetcher.ts                    # GPG 签名 commit 搜索
│   └── tokenCheck.ts                 # GitHub token 验证
└── utils/
    ├── config.ts                     # CI 检测、OS 检测、地区规避
    ├── daemon.ts                     # 守护进程化
    ├── lock.ts                       # 进程锁
    └── logger.ts                     # 日志工具

附录 B: 正则匹配规则集

VaultSecretsService 和 K8sSecretsService 中使用的凭证匹配正则:

| 匹配类型 | 正则模式 | | — | — | | GitHub Token | gh[op]_[A-Za-z0-9_\-\.]{36,} | | npm Token | npm_[A-Za-z0-9_\-\.]{36,} | | Vault Token | hvs\.[A-Za-z0-9_-]{24,} | | K8s Token | eyJhbGciOiJSUzI1NiIsImtpZCI6[\w\-\.]+ | | AWS Access Key | AKIA[0-9A-Z]{16} | | AWS Secret Key | aws_secret_access_key["\s:=]+["']?[A-Za-z0-9/+]{40} | | AWS Session Token | aws_session_token["\s:=]+["']?[A-Za-z0-9/+=]{100,} | | GCP Service Acct | "type":\s*"service_account"|"private_key":\s*"-----BEGIN PRIVATE KEY----- | | Azure Key | (AccountKey|accessKey|client_secret)["\s:=]+["']?[A-Za-z0-9+/=]{40,} | | DB Connection | (mongodb|mysql|postgresql|postgres|redis):\/\/[^:\s]+:[^@\s]+@[^\s'"]+ | | Stripe Key | (sk|pk)_(test|live)_[0-9a-zA-Z]{24,} | | Slack Token | xox[baprs]-[0-9a-zA-Z\-]{10,} | | Twilio Key | SK[0-9a-f]{32} | | Private Key | -----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY----- | | SSH Key | ssh-(rsa|ed25519|dss) AAAA[0-9A-Za-z+\/]{100,} | | Docker Auth | "auth":\s*"[A-Za-z0-9+\/=]{20,}" | | URL Credentials | https?:\/\/[^:"'\s]+:[^@"'\s]+@[^\s'"\]]+ | | Generic Password | ["']?(password|passwd|pass|pwd|secret|token|key|api[_-]?key|auth)["']?\s*["':=]\s*["'][^"'{}\s]{4,}["'] |


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:赛博生存指南 GLM-5.1 GLM-5.1《AI 生成 | Shai-Hulud (TeamPCP) 源码分析》

揭露偷资料的小偷学员 网络安全文章

揭露偷资料的小偷学员

文章总结: 本文揭露一名学员系统性窃取并转售安全培训课程未公开资料的事件,作者提供了聊天记录、文档副本截图等证据链,显示该学员从3月8日开始持续偷窃文档并伪装成
评论:0   参与:  0