Abusing Github Actions
基本情報
このページでは以下が見つかります:
攻撃者がGithub Actionにアクセスできる場合のすべての影響の要約
アクションにアクセスするための異なる方法:
アクションを作成する権限を持っている
プルリクエスト関連のトリガーを悪用する
他の外部アクセス技術を悪用する
すでに侵害されたリポジトリからピボットする
最後に、アクションを悪用するためのポストエクスプロイテーション技術についてのセクション(上記の影響を引き起こす)
影響の要約
Github Actionsの基本情報をチェックして、導入について学びます。
リポジトリで任意のGithubアクションを実行/コードをインジェクトできる場合、次のことができるかもしれません:
そのリポジトリ/組織からシークレットを盗む
インジェクトのみが可能な場合、ワークフローにすでに存在するものを盗むことができます。
AWSやGCPなど他のプラットフォームにアクセスするためにリポジトリの権限を悪用する
カスタムワーカーでコードを実行し、そこからピボットを試みる
リポジトリのコードを上書きする
これは
GITHUB_TOKEN
の権限に依存します(あれば)デプロイメントや他のアーティファクトを侵害する
コードが何かをデプロイしたり保存している場合、それを変更してさらなるアクセスを取得できます。
GITHUB_TOKEN
この「シークレット」(${{ secrets.GITHUB_TOKEN }}
および${{ github.token }}
から来ます)は、管理者がこのオプションを有効にしたときに与えられます:
このトークンはGithubアプリケーションが使用するものと同じなので、同じエンドポイントにアクセスできます:https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Githubは、リポジトリがGITHUB_TOKEN
を使用して他の内部リポジトリにアクセスできるようにするフローをリリースすべきです。
このトークンの可能な権限は次の場所で確認できます:https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
このトークンは、ジョブが完了した後に期限切れになります。
これらのトークンは次のように見えます:ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
このトークンでできる興味深いこと:
複数の場合には、Github Actions envs内またはシークレット内にgithubユーザートークンを見つけることができることに注意してください。これらのトークンは、リポジトリや組織に対するより多くの特権を与える可能性があります。
他のユーザーのリポジトリでGithubトークンに与えられた権限をチェックすることが可能です。アクションのログをチェックすることで:
許可された実行
これはGithubアクションを妨害する最も簡単な方法であり、この場合は組織内で新しいリポジトリを作成する権限があるか、リポジトリに書き込み権限があると仮定しています。
このシナリオにいる場合は、ポストエクスプロイテーションテクニックをチェックするだけで済みます。
リポジトリ作成からの実行
組織のメンバーが新しいリポジトリを作成でき、Githubアクションを実行できる場合、新しいリポジトリを作成し、組織レベルで設定されたシークレットを盗むことができます。
新しいブランチからの実行
すでにGithubアクションが構成されているリポジトリに新しいブランチを作成できる場合、それを変更し、コンテンツをアップロードしてから、新しいブランチからそのアクションを実行することができます。これにより、リポジトリおよび組織レベルのシークレットを外部に送信することができます(ただし、それらがどのように呼ばれるかを知っている必要があります)。
変更されたアクションを手動で実行したり、PRが作成されたときやコードがプッシュされたときに実行したりすることができます(どれくらい騒々しいかによります)。
フォークされた実行
攻撃者が他のリポジトリのGithubアクションを実行することを可能にするさまざまなトリガーがあります。これらのトリガー可能なアクションが適切に構成されていない場合、攻撃者はそれらを妨害できるかもしれません。
pull_request
pull_request
ワークフロートリガー**pull_request
は、プルリクエストが受信されるたびにワークフローを実行しますが、いくつかの例外があります:デフォルトでは、初めて協力する場合、メンテナーがワークフローの実行を承認**する必要があります:
デフォルトの制限は初めての貢献者向けですので、有効なバグ/タイポを修正してから新しいpull_request
権限を悪用するために他のPRを送信できます。
これをテストしましたが機能しません: 別のオプションとして、プロジェクトに貢献した人の名前でアカウントを作成し、そのアカウントを削除することが考えられます。
さらに、デフォルトでは、ドキュメントで言及されているように、書き込み権限とシークレットアクセスが対象リポジトリに対してデフォルトで防止されます:
GITHUB_TOKEN
を除いて、シークレットはフォークされたリポジトリからのプルリクエストでワークフローがトリガーされたときにランナーに渡されません。GITHUB_TOKEN
は、フォークされたリポジトリからのプルリクエストで読み取り専用権限**を持ちます。
攻撃者はGithubアクションの定義を変更して任意のことを実行し、任意のアクションを追加することができます。ただし、上記の制限のため、シークレットを盗むことやリポジトリを上書きすることはできません。
はい、攻撃者がPRでトリガーされるgithubアクションを変更すると、彼のGithubアクションが使用され、元のリポジトリのものは使用されません!
攻撃者は実行されるコードも制御しているため、GITHUB_TOKEN
にシークレットや書き込み権限がなくても、例えば悪意のあるアーティファクトをアップロードすることができます。
pull_request_target
pull_request_target
ワークフロートリガー**pull_request_target
は、対象リポジトリに書き込み権限とシークレットへのアクセス**(許可を求めない)を持っています。
ワークフロートリガー**pull_request_target
はベースコンテキスト**で実行され、PRで与えられたコンテキストではないことに注意してください(信頼できないコードを実行しない)。pull_request_target
についての詳細は、ドキュメントを参照してください。
さらに、この特定の危険な使用についての詳細については、このgithubブログ記事をチェックしてください。
実行されるワークフローがベースで定義されており、PRではないため、pull_request_target
を使用するのは安全であるように見えるかもしれませんが、そうでない場合もあります。
そして、これにはシークレットへのアクセスがあります。
workflow_run
workflow_run
workflow_runトリガーは、completed
、requested
、またはin_progress
のときに別のワークフローを実行することを可能にします。
この例では、別々の"Run Tests"ワークフローが完了した後にワークフローが実行されるように構成されています:
さらに、ドキュメントによると、workflow_run
イベントによって開始されたワークフローは、前のワークフローがなくてもシークレットにアクセスし、トークンを書き込むことができる。
この種のワークフローは、pull_request
または pull_request_target
を介して外部ユーザーによってトリガーされる可能性がある ワークフロー に依存している場合、攻撃される可能性があります。脆弱な例は、このブログ で見つけることができます。最初の例は、workflow_run
がトリガーされたワークフローが攻撃者のコードをダウンロードすることです: ${{ github.event.pull_request.head.sha }}
2番目の例は、信頼できないコードから workflow_run
ワークフローに アーティファクト を渡し、このアーティファクトの内容を使用して RCE に脆弱 にする方法です。
workflow_call
workflow_call
TODO
TODO: 実行時に pull_request から使用/ダウンロードされたコードが、元のものかフォークされた PR のものかを確認する
フォークされた実行の悪用
外部攻撃者が GitHub ワークフローを実行する方法についてすべて説明しましたが、今度は、これらの実行が誤って構成されている場合にどのように悪用される可能性があるかを見てみましょう:
信頼できないチェックアウト実行
pull_request
の場合、ワークフローは PR のコンテキストで実行 されます(つまり、悪意のある PR のコード が実行されます)、ただし、最初に 承認する必要があり、いくつかの制限で実行されます。
pull_request_target
または workflow_run
を使用するワークフローが、pull_request_target
または pull_request
からトリガーされるワークフローに依存している場合、元のリポジトリのコードが実行されるため、攻撃者は実行されるコードを制御できません。
ただし、アクションに 明示的な PR チェックアウト がある場合、PR のコードが取得され(ベースではなく)、攻撃者が制御するコードが使用されます。例えば(PR コードがダウンロードされる行 12 を確認してください):
潜在的に 信頼できないコードが npm install
または npm build
の実行時に実行 されるため、ビルドスクリプトと参照される パッケージは PR の著者によって制御 されます。
脆弱なアクションを検索するための GitHub ドークは、event.pull_request pull_request_target extension:yml
ですが、アクションが不適切に構成されていても、ジョブを安全に実行するさまざまな方法があります(PR を生成するアクターに関する条件分岐を使用するなど)。
コンテキストスクリプトインジェクション
特定のGitHub コンテキストの値が PR を作成するユーザーによって制御 されることに注意してください。GitHub アクションがそのデータを使用して何かを実行している場合、任意のコードの実行につながる 可能性があります:
pageGh Actions - Context Script InjectionsGITHUB_ENV スクリプトインジェクション
ドキュメントによると、GITHUB_ENV
環境ファイルに環境変数を定義または更新して、ワークフロージョブの後続のステップでその環境変数を利用できるようにすることができます。
攻撃者がこの env 変数に任意の値を インジェクト できれば、後続のステップでコードを実行するための環境変数をインジェクトできるため、LD_PRELOAD や NODE_OPTIONS などの環境変数をインジェクトできます。
例えば(こちら および こちら)、アップロードされたアーティファクトを信頼してその内容を GITHUB_ENV
環境変数に格納するワークフローを想像してください。攻撃者は、これを妨害するために次のようなものをアップロードできます:
脆弱なサードパーティ GitHub アクション
このブログ記事 で述べられているように、この GitHub アクションを使用すると、異なるワークフローやリポジトリからアーティファクトにアクセスできます。
問題は、path
パラメータが設定されていない場合、アーティファクトが現在のディレクトリに展開され、後で使用されるか、ワークフローで実行される可能性があるファイルを上書きできることです。したがって、アーティファクトが脆弱な場合、攻撃者はこれを悪用して、アーティファクトを信頼する他のワークフローを妨害できます。
脆弱なワークフローの例:
これは次のワークフローで攻撃される可能性があります:
その他の外部アクセス
削除されたネームスペースリポジトリの乗っ取り
アカウントが名前を変更すると、しばらくしてから別のユーザーがその名前でアカウントを登録することができます。リポジトリが名前を変更する前に100個未満のスターがついていた場合、Githubは同じ名前のリポジトリを作成することができるようになります。
したがって、アクションが存在しないアカウントからリポジトリを使用している場合、攻撃者がそのアカウントを作成し、アクションを妨害する可能性があります。
他のリポジトリがこのユーザーリポジトリからの依存関係を使用している場合、攻撃者はそれらを乗っ取ることができます。詳細な説明はこちらを参照してください: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
リポジトリのピボット
このセクションでは、最初のリポジトリに何らかのアクセス権があると仮定して、1つのリポジトリから別のリポジトリにピボットする技術について説明します(前のセクションを参照)。
キャッシュの汚染
同じブランチでのワークフロー実行間にはキャッシュが維持されます。つまり、攻撃者がキャッシュに保存され、より特権のあるワークフローによってダウンロードおよび実行されるパッケージを妨害すると、そのワークフローも妨害される可能性があります。
pageGH Actions - Cache Poisoningアーティファクトの汚染
ワークフローは他のワークフローおよびリポジトリからアーティファクトを使用することができます。攻撃者が後で別のワークフローで使用されるアーティファクトをアップロードするGithubアクションを妨害すると、他のワークフローも妨害される可能性があります。
pageGh Actions - Artifact Poisoningアクションからのポストエクスプロイテーション
OIDCを介したAWSおよびGCPへのアクセス
以下のページを確認してください:
pageAWS - Federation AbusepageGCP - Federation Abuseシークレットへのアクセス
スクリプトにコンテンツを注入している場合、シークレットにアクセスする方法を知っておくと便利です:
シークレットまたはトークンが環境変数に設定されている場合、**
printenv
**を使用して環境を介して直接アクセスできます。
If the secret is used directly in an expression, the generated shell script is stored on-disk and is accessible.
cat /home/runner/work/_temp/*
For a custom action, the risk can vary depending on how a program is using the secret it obtained from the argument:
Self-hosted runnersの悪用
Githubインフラ以外で実行されているGithub Actionsを見つける方法は、Github Actionの構成yamlで**runs-on: self-hosted
**を検索することです。
Self-hostedランナーは、追加の機密情報、他のネットワークシステム(ネットワーク内の脆弱なエンドポイント?メタデータサービス?)へのアクセス権を持っている可能性があります。また、孤立して破棄されていても、複数のアクションが同時に実行される可能性があり、悪意のあるアクションが他のアクションのシークレットを盗むことができます。
Self-hostedランナーでは、メモリをダンプすることで、_Runner.Listenerプロセスからシークレットを取得することも可能です:
詳細については、この投稿をチェックしてください。
Github Docker Images Registry
Github内にDockerイメージをビルドして保存するGithubアクションを作成することが可能です。 以下に例を示します。
前のコードでわかるように、Githubレジストリは**ghcr.io
**にホストされています。
リポジトリに読み取り権限を持つユーザーは、パーソナルアクセス トークンを使用してDockerイメージをダウンロードできます:
ユーザーは、Dockerイメージのレイヤー内で漏洩したシークレットを検索できます:
Github Actionsログ内の機密情報
Githubはアクションログ内のシークレット値を検出しようとして非表示にするが、アクションの実行中に生成された他の機密データは非表示にされません。たとえば、シークレット値で署名されたJWTは、特に設定されていない限り非表示にされません。
足跡を隠す
(こちらの技術)まず、公開されたGithubと対象のGitHubアカウントでPRが明確に表示されます。GitHubではデフォルトで、インターネット上のPRを削除することはできませんが、ひとつ裏技があります。GitHubによって停止されたGitHubアカウントの場合、すべてのPRが自動的に削除され、インターネットから削除されます。したがって、活動を隠すためには、GitHubアカウントを停止させるか、アカウントをフラグ付きにする必要があります。これにより、GitHub上のすべての活動がインターネットから非表示になります(基本的にすべての悪用PRを削除します)。
GitHubの組織は、GitHubにアカウントを報告することに非常に積極的です。Issueで「何か」を共有するだけで、12時間以内にアカウントが停止されるようになります:p そしてそこで、GitHub上のあなたの悪用が見えなくなります。
組織が標的にされたことに気づく唯一の方法は、GitHub UIからPRが削除されるため、SIEMからGitHubログを確認することです。
ツール
以下のツールは、Github Actionワークフローを見つけたり、脆弱なものを見つけたりするのに役立ちます:
最終更新