Featured image of post ActionOPs - WriteUp

ActionOPs - WriteUp

紧急插播一条受害者新闻

介绍

这是一道由裙友 @Esonhugh 出的益智Quiz,趁着最近也有空,就打着看一下。在流程中一边看边学 Github Action/Authentication 相关的知识也是非常的寓教于乐了。

题目链接 actionops.github.io

Step 1 分析

首先点击链接,进入到平平无奇的首页,发现这是一个 Github Pages 页面,Github Pages 的二级域名默认是Github用户名,让我们顺着网线找过去。

首页 用户页 仓库页

到用户页后发现隐藏了活动日志,不要紧,能看到有两个 Repositories,其中一个是刚刚看到的 Github Pages 所在的仓库 actionops.github.io ,见到 Git 仓库下意识的先看看 commit 记录。

可以看到 commit 记录里有两个值得关注的地方,一个 commit 记录题为 test overwrite,还有一个html页上写了 Try Hcak My Account, And leave your name at following table,是不是拿下这个用户暂时还不清楚,但是可以确定 目标是修改这个仓库的 index.html 文件。

actionops.github.io 仓库

接下来看看 testing-frontend 仓库, testing-frontend 仓库在 init project 后主要的修改都是在更新持续集成的配置,在 testing-frontend/.github/workflows/ci.yaml 文件中,猜测是当 main 仓库发生 push 动作时会 调用 nrkno/github-workflow-docker-build-push 将仓库的代码打包成 docker 镜像并上传至 docker.io。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
name: CI with secrets

on:
  push:
    branches: [main]

permissions: write-all

jobs:
  build-push:
    uses: nrkno/github-workflow-docker-build-push/.github/workflows/workflow.yaml@v4.0.0
    with:
      runs-on: "['ubuntu-latest']"
      registry-url: docker.io
      name: iknowgha/i-dont-know-security
      # Tag with 'latest' tag when merging to main
      tag-latest: true
      push: true
      trivy-severity: "CRITICAL"
      trivy-error-is-success: true
      trivy-enabled: false
    secrets:
      registry-username: ${{ secrets.DOCKER_USER }}
      registry-password: ${{ secrets.DOCKER_PASS }}
      token: ${{ secrets.CI_TOKEN }}

通过分析 ci.yaml 可以看到分析的三个关键点:

Step 2 思考

一般来说 secrets 在 Github 上是看不到的,这个仓库也没有开放 Actions 执行日志的查看权限,接着看 github-workflow-docker-build-push 这个仓库。

ci.yaml 中,指定了 workflow.yaml 的版本是 @v4.0.0,现在最新版本是 @v4.0.1 看看 commit diff,是不是修了什么能够利用的漏洞?

根本就只是依赖更新!

事实证明我想多了,,没啥重点,接着看。

看到 workflow.yaml 中,on.workflow_call 有一组 secrets 的传入参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
secrets:
  registry-username:
    description: Username for the container registry.
    required: true
  registry-password:
    description: Password for the container registry.
    required: true
  token:
    description: GitHub auth token.
    required: true

基本上就是 ci.yamlsecrets 的传入参数的介绍,可以看到 token 描述为 GitHub auth token 。思考中…那拿下 secrets.token 是不是就能拿下账号了?

粗略看看 workflow.yaml 中, jobs.steps 有:

  • Set environment
  • Checkout
  • Set up Docker Buildx
  • Build
  • Push

这个时候先入为主了,完全忘记刚刚看的时候没有运行容器测试,之前在使用 GitHub Actions 的时候,一般都是把都 secrets 放进容器里的 环境变量 中,然后运行测试,测试成功后再发布相关资源,框框进行了一顿错误的猜测。

那这样好啊(叉腰

  • Workflow执行
  • 进入Github的容器
  • pull源码
  • 设置 environment
  • 测试编译
  • 存到日志里了!
  • Get Token!

你在幻想什么不存在的东西

Step 3 岔路

接下来顺着自己的思路就是直接框框一顿

1
2
docker pull iknowgha/i-dont-know-security
docker image save iknowgha/i-dont-know-security -o idk.tar

为什么不是将容器run起来而是保存镜像文件呢?这里其实是怕作者在代码里面加了不干净的东西。

Update 1:这波也确实是预判作者的预判了

更新

在最近的一次更新中,特别强调地删除了 .git 文件夹,但是是在容器运行后删除的,对直接分析镜像文件无效 要是我早一点看到也不用想着去翻垃圾了

将image保存为tar包后,拖到Windows进行7z大法。

7z大法

有很多乱的东西,不要紧7z能打开的就用7z打开,7z不能打开的用二进制编辑器一开,都是文本文件。

错误的答案1

就这样找了半个小时的logs/secrets/env…完全翻不到 token 啊!!!

Take a break.事已至此,先吃饭吧。

Step 4 好起来了

饭后开始 栈回溯 分析过程,又回到 workflow.yaml 中一探究竟,发现 secrets.token 其实只传给了 actions/checkout@v4 这个 Action。

1
2
3
4
5
6
7
name: Checkout
uses: actions/checkout@v4
with:
    ref: ${{ inputs.git-ref }}
    token: ${{ secrets.token }}
    submodules: ${{ inputs.git-submodules }}
    ssh-key: ${{ secrets.git-ssh-key }}

而这个 Checkout 是干什么的呢?所幸,在 github-workflow-docker-build-push 中有这个 Action 的测试,也有测试日志。

Checkout!

通过分析测试日志,发现 Checkout 其实是个在容器中用来拉取仓库资源并使用 传入的Token,写入本地Git仓库,作为Github权限校验的凭据,以便后续进行一系列的Git操作。

这下一目了然了,首先找到这个 git --local 的配置存储在哪里。

还是7z大法

直接看到 .git/config 中有

1
2
[http "https://github.com/"]
	extraheader = AUTHORIZATION: basic <一串Base64>

看到Base64,拿去 CyberChef 解一下。

解出来是 x-access-token:ghp_T4gj3Le1**********BHHN,拿去咕咕噜一搜,搜出来是 GitHub Personal Access Tokens,基本上有这个就有一部分的权限了。

尝试将 Github Pages 的仓库 clone 到本地,自己 commit 个提交,再修改clone下来的本地repo .git/config ,写入镜像中泄露出的 extraheader 配置。

一顿 git push 成了!

Finfish

结束后思考

不知道 @Esonhugh 是从哪里看到这个 Workflow 的呢,存在问题的主要地方还是 Checkout 后,将不必要的文件打包成为了镜像,并传到了 Docker Hub,看了几个大的项目,基本上都只是通过Docker Hub分发 dist/ output/ 目录下的文件,杜绝了将敏感信息打包进镜像(比如 Checkout 后的 .git 文件夹),从而防止泄露。

这个Action使用的范围不是很广泛

[[还有一些想说的,后面再更新吧]]

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计