从扫描器到失陷器:Trivy供应链攻击技术还原
文章目录
从扫描器到失陷器:Trivy供应链攻击技术还原
2026年3月19日,开源安全圈迎来了一次教科书级的供应链攻击事件。
Aqua Security旗下的明星项目——Trivy漏洞扫描器——官方GitHub Actions被入侵,75个发布标签遭篡改,含有凭证窃取恶意代码的二进制文件通过官方渠道(GitHub Releases、Docker Hub、ECR)分发。
这不是一次普通的供应链攻击。它的讽刺之处在于:安全工具本身成为了攻击入口。一个被全球开发者信任用于扫描漏洞的工具,反而成了投递恶意载荷的载体。
本文将从技术角度完整还原这次攻击的攻击链,分析其成因,并给出实用的检测和防护方案。
一、攻击时序还原
阶段一:潜入(Late February 2026)
攻击者使用一个名为hackerbot-claw的自动化机器人,利用了Trivy项目GitHub Actions中pull_request_target工作流的权限错误配置。
pull_request_target是GitHub Actions中一个特殊触发器,当有人提交PR到仓库时触发。但问题在于:它会在具有仓库写入权限的上下文中运行——这意味着攻击者可以通过构造一个PR,让自己的代码在具有高权限的环境中执行。
攻击者提交了一个包含恶意代码的PR,从中提取了一个具有特权的Personal Access Token(PAT)。
阶段二:横向移动(Late February – Early March 2026)
获取PAT后,攻击者利用这个凭证获得了对Trivy GitHub仓库自动化流程的访问权限,并开始在release发布流程中埋入后门。
阶段三:信任伪造(March 19, 2026 – 17:43:37 UTC)
关键一步:攻击者伪造了知名开发者的commits身份(spoofing rauchg和DmitriyLewen等真实贡献者),向仓库推送了伪造的commit。
当tag被推送时,GitHub Actions自动触发release构建流程。此时,恶意代码被注入:它从 typosquatting域名scan.aquasecurtiy[.]org(注意aquasecurtiy而非aquasecurity)拉取凭证窃取程序,同时构建出的二进制文件也被植入后门。
17:43:37 UTC,Trivy仓库的tag被推送,污染的release正式生效。
阶段四:分发(March 19–22 2026)
污染的二进制文件通过多个渠道分发:
- GitHub Releases
- Docker Hub
- GHCR(GitHub Container Registry)
- Amazon ECR
- CloudFront CDN
CrowdStrike Falcon平台率先在多个客户环境中检测到异常的脚本执行行为,溯源到了被污染的aquasecurity/trivy-action。
二、攻击链技术拆解
pull_request_target权限滥用
↓
窃取PAT(Personal Access Token)
↓
获得仓库自动化权限
↓
注入release构建流程
↓
伪造commits(冒充真实开发者)
↓
tag push触发恶意构建
↓
从typosquatting域名拉取payload
↓
分发污染的二进制/容器镜像
关键攻击技术点
1. pull_request_target的陷阱
pull_request_target触发器在以下上下文中运行:
- 来自fork PR:基础仓库的上下文(通常安全)
- 来自同一仓库的PR:具有写权限的仓库上下文(危险!)
攻击者利用了第二种情况。在正常开源项目中,外部贡献者通过fork+PR提交代码,但某些仓库会在PR中也使用pull_request_target,导致恶意代码在高权限上下文中执行。
2. Typosquatting域名
合法域名:scan.aquasecurity.com
伪造域名:scan.aquasecurtiy.org (typosquatting,注意多了个"i")
攻击者注册的伪造域名解析到45.148.10.212,用于托管凭证窃取程序。这种攻击方式对依赖拼写相似的域名诱骗极为有效。
3. Commit身份伪造
攻击者向actions/checkout和aquasecurity/trivy仓库推送了伪造commit,冒充了真实开发者rauchtg和DmitriyLewen。这说明攻击者不仅获取了仓库写权限,还掌握了这些开发者的git配置信息。
三、技术指标(IoCs)
| 类型 | 指标 |
|---|---|
| 恶意域名 | scan.aquasecurtiy[.]org |
| 恶意IP | 45.148.10.212 |
| 恶意SHA256(已知样本) | 搜索Aqua Security官方 advisories |
| 受影响版本范围 | 2026年3月19日后构建的release标签 |
| C2通信特征 | DNS查询 scan.aquasecurtiy.org |
| 攻击者组织 | TeamPCP |
四、如何检测自己是否受影响
4.1 检查Trivy版本
# 查看当前Trivy版本
trivy --version
# 如果版本构建时间在2026年3月19日之后,建议立即替换
4.2 检查CI/CD日志
检查CI/CD pipeline执行日志中是否存在对以下域名的DNS解析:
# 如果你使用的是自架DNS服务器,检查查询日志
grep "aquasecurtiy" /var/log/dns.log
# 或在Cloudflare等DNS服务商后台查询
4.3 检查凭证访问
回顾CI/CD环境中最近是否有异常凭证访问:
# 检查GitHub Actions环境变量中是否有凭证被异常读取
# 审查GitHub仓库的Security log,看是否有来自异常IP的PAT使用
# 检查SIEM中的异常脚本执行告警(CrowdStrike用户关注Falcon告警)
4.4 检查网络流量
在防火墙或代理日志中搜索以下模式:
# 恶意域名
scan.aquasecurtiy.org
# 恶意IP
45.148.10.212
# Trivy 二进制下载的可疑模式
aquasec.io 或 aquasecurtiy.org
五、应急响应步骤
Step 1:立即隔离
如果确认使用了受污染版本:
- 立即停止使用当前Trivy版本,切换到已知安全版本或临时替代方案
- 在CI/CD pipeline中临时禁用Trivy,或指向可信的代理/镜像
- 隔离可疑的CI/CD runner环境
Step 2:轮换凭证
所有在CI/CD环境中使用或暴露过的凭证必须立即轮换:
- GitHub/GitLab Personal Access Tokens
- 云服务商Access Keys(AWS IAM keys, Azure SAS tokens等)
- Docker Hub / GHCR / ECR 认证信息
- 任何在CI/CD pipeline中传递过的密钥
Step 3:检查Artifact完整性
# 验证从GitHub Releases下载的Trivy二进制
# 1. 检查官方博客提供的已知安全版本的SHA256
# 2. 比对当前使用版本的SHA256
# 使用 Aqua Security 官方提供的验证工具(参见文末链接)
Step 4:审查发布渠道
如果你的系统从Docker Hub、ECR等渠道拉取Trivy镜像:
# 检查最近拉取的Trivy镜像tag
docker images | grep trivy
# 拉取官方最新确认的安全版本
docker pull aquasec/trivy:<safe-version>
# 或使用GitHub官方发布的二进制
wget https://github.com/aquasecurity/trivy/releases/download/<safe-version>/trivy_<safe-version>_linux_amd64.tar.gz
六、防护建议
6.1 GitHub Actions安全加固
# .github/workflows/ci.yml 示例:安全配置
name: CI
on:
push:
branches: [main]
pull_request:
# 使用 pull_request 而非 pull_request_target
# 除非你完全理解其安全含义
jobs:
security:
permissions:
# 最小权限原则
contents: read
actions: read
security-events: write
关键建议:
- 永远不要在
pull_request_target中运行来自PR的不可信代码 - 如果必须在PR中运行代码,使用
pull_request触发器,并在隔离的runner中执行 - 对所有Actions使用版本pinning(而非@master或@main)
- 启用GitHub的依赖审查(Dependency review)和安全 Advisories
6.2 CI/CD管道签名验证
对所有下载的二进制实施签名验证:
# 示例:Trivy官方提供的cosign签名验证(如果已恢复签名机制)
cosign verify \
--certificate-identity "https://github.com/aquasecurity/trivy" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
aquasec/trivy:0.50.0
6.3 供应链安全工具链
建议在CI/CD中集成以下工具形成纵深防御:
- Sigstore / cosign:对容器镜像和二进制进行签名验证
- SLSA框架:检查构建过程的provenance
- Dependabot / Renovate:自动更新依赖到安全版本
- Grype:作为Trivy的备份扫描器
- Docker Scout:Docker官方安全工具
6.4 最小权限原则
审查所有CI/CD服务账号的权限:
# GitHub - 检查PAT权限范围
# 删除不必要的工作流权限
# 云服务商 - 使用临时凭证(OIDC)
# 避免在环境变量中存储长期密钥
七、这次事件教会我们什么
1. 安全工具不等于安全
Trivy被入侵的核心讽刺在于:它是用来发现漏洞的工具,现在反而成了漏洞的来源。这提醒我们:对供应链的信任应该是有条件的、可验证的,而不是无条件的。
2. pull_request_target是双刃剑
这个触发器的设计初衷是好的(方便PR作者在发布分支上测试),但一旦在错误上下文中使用,就会成为特权代码执行的入口。任何使用pull_request_target的项目都应该重新审查其安全性。
3. 签名验证是必选项
在没有二进制签名验证的情况下,分发渠道(GitHub Releases、Docker Hub)只能提供"来源正确"的假象,无法保证"内容未被篡改"。cosign/SLSA应该成为现代CI/CD的标准配置。
4. 凭证轮换必须成为习惯
许多开发者在CI/CD泄露后才意识到凭证暴露的危害。在发现供应链异常后,第一反应应该是立即轮换所有相关凭证,而不是等确认为什么泄露。
参考链接
- Aqua Security 官方公告
- Wiz Blog – Trivy Compromised by TeamPCP
- CrowdStrike – From Scanner to Stealer
- The Hacker News – Trivy Security Scanner GitHub Actions Breached
- Ars Technica – Widely used Trivy scanner compromised
本文会持续更新,如有任何补充或勘误,欢迎通过文末方式联系作者。