GCP - Artifact Registry Privesc

Support HackTricks

Artifact Registry

Artifact Registry에 대한 자세한 정보는 다음을 확인하세요:

artifactregistry.repositories.uploadArtifacts

이 권한을 통해 공격자는 Docker 이미지와 같은 악성 코드를 포함한 아티팩트의 새 버전을 업로드할 수 있습니다:

# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev

# tag the image to upload it
docker tag <local-img-name>:<local-tag> <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

# Upload it
docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

이미 존재하는 것과 동일한 이름과 태그를 가진 새로운 악성 docker 이미지를 업로드하는 것이 가능하다는 것이 확인되었습니다, 따라서 이전 이미지는 태그를 잃게 되고 다음에 해당 태그로 다운로드될 때 악성 이미지가 다운로드됩니다.

Python 라이브러리 업로드

업로드할 라이브러리를 생성하는 것부터 시작하세요 (레지스트리에서 최신 버전을 다운로드할 수 있다면 이 단계를 건너뛸 수 있습니다):

  1. 프로젝트 구조 설정:

  • 라이브러리를 위한 새 디렉토리를 생성합니다, 예: hello_world_library.

  • 이 디렉토리 안에 패키지 이름으로 또 다른 디렉토리를 생성합니다, 예: hello_world.

  • 패키지 디렉토리 안에 __init__.py 파일을 생성합니다. 이 파일은 비어있거나 패키지 초기화를 포함할 수 있습니다.

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
from setuptools import setup, find_packages

setup(
name='hello_world',
version='0.1',
packages=find_packages(),
install_requires=[
# 라이브러리에 필요한 종속성
],
)

이제 라이브러리를 업로드합시다:

  1. 패키지 빌드:

  • hello_world_library 디렉토리의 루트에서 다음을 실행합니다:

python3 setup.py sdist bdist_wheel
  1. 패키지 업로드를 위한 twine 인증 구성:

  • twine이 설치되어 있는지 확인합니다 (pip install twine).

  • gcloud를 사용하여 자격 증명을 구성합니다:

```sh
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
```
  1. 빌드를 정리하기

rm -rf dist build hello_world.egg-info

이미 존재하는 것과 동일한 버전의 파이썬 라이브러리를 업로드하는 것은 불가능하지만, 더 높은 버전을 업로드하거나 (작동한다면 버전 끝에 .0을 추가할 수 있음 - 파이썬에서는 아님), 또는 마지막 버전을 삭제하고 새로운 버전을 업로드할 수 있습니다 (필요한 artifactregistry.versions.delete):

gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>

artifactregistry.repositories.downloadArtifacts

이 권한을 사용하면 아티팩트다운로드하고 민감한 정보취약점을 검색할 수 있습니다.

Docker 이미지를 다운로드:

# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev

# Dowload image
docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

Download a python 라이브러리:

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
  • 원격 레지스트리와 표준 레지스트리가 가상 레지스트리에서 혼합되고 두 곳 모두에 패키지가 존재하면 어떻게 될까요? 이 페이지를 확인하세요:

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

레지스트리에서 아티팩트를 삭제합니다. 예: 도커 이미지:

# Delete a docker image
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>

artifactregistry.repositories.delete

전체 리포지토리를 삭제합니다(내용이 있더라도):

gcloud artifacts repositories delete <repo-name> --location=<location>

artifactregistry.repositories.setIamPolicy

이 권한을 가진 공격자는 이전에 언급된 일부 리포지토리 공격을 수행할 수 있는 권한을 스스로 부여할 수 있습니다.

Artifact Registry 읽기 및 쓰기를 통한 다른 서비스로의 피벗

  • Cloud Functions

Cloud Function이 생성될 때 새로운 도커 이미지가 프로젝트의 Artifact Registry에 푸시됩니다. 나는 이미지를 새로운 것으로 수정하려고 시도했으며, 현재 이미지를 삭제하고(cache 이미지도) 아무것도 변경되지 않았습니다. 클라우드 함수는 계속 작동합니다. 따라서, 아마도 버킷과 같은 경쟁 조건 공격을 악용하여 실행될 도커 컨테이너를 변경할 수 있을지도 모릅니다. 그러나 저장된 이미지를 수정하는 것만으로는 Cloud Function을 손상시킬 수 없습니다.

  • App Engine

App Engine이 Artifact Registry 내에서 도커 이미지를 생성하더라도, 이 서비스 내에서 이미지를 수정하고 App Engine 인스턴스를 제거(새 인스턴스가 배포됨)하더라도 실행되는 코드는 변경되지 않습니다. 버킷과 같은 경쟁 조건 공격을 수행하면 실행되는 코드를 덮어쓸 수 있을지도 모르지만, 이는 테스트되지 않았습니다.

Support HackTricks

Last updated