从扫描器到失陷器: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权限滥用
        
窃取PATPersonal 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/checkoutaquasecurity/trivy仓库推送了伪造commit,冒充了真实开发者rauchtgDmitriyLewen。这说明攻击者不仅获取了仓库写权限,还掌握了这些开发者的git配置信息。


三、技术指标(IoCs)

类型指标
恶意域名scan.aquasecurtiy[.]org
恶意IP45.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:立即隔离

如果确认使用了受污染版本:

  1. 立即停止使用当前Trivy版本,切换到已知安全版本或临时替代方案
  2. 在CI/CD pipeline中临时禁用Trivy,或指向可信的代理/镜像
  3. 隔离可疑的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泄露后才意识到凭证暴露的危害。在发现供应链异常后,第一反应应该是立即轮换所有相关凭证,而不是等确认为什么泄露。


参考链接


本文会持续更新,如有任何补充或勘误,欢迎通过文末方式联系作者。