GCP - Storage Privesc

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Armazenamento

Basic Information:

GCP - Storage Enum

storage.objects.get

Esta permissão permite que você faça download de arquivos armazenados dentro do Cloud Storage. Isso pode potencialmente permitir escalar privilégios porque, em algumas ocasiões, informações sensíveis são salvas lá. Além disso, alguns serviços do GCP armazenam suas informações em buckets:

  • GCP Composer: Quando você cria um Composer Environment o código de todos os DAGs será salvo dentro de um bucket. Essas tarefas podem conter informações interessantes dentro do seu código.
  • GCR (Container Registry): A imagem dos containers é armazenada dentro de buckets, o que significa que se você puder ler os buckets será capaz de baixar as imagens e procurar por leaks e/ou código-fonte.

storage.objects.setIamPolicy

Essa permissão permite que você abuse de qualquer um dos cenários anteriores desta seção.

# Add binding
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>

# Remove binding
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>

# Change Policy
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY

storage.buckets.setIamPolicy

Para um exemplo de como modificar permissões com essa permissão, veja esta página:

# Add binding
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>

# Remove binding
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>

# Change policy
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY

GCP - Public Buckets Privilege Escalation

storage.hmacKeys.create

A funcionalidade “interoperability” do Cloud Storage, projetada para cross-cloud interactions como com AWS S3, envolve a criação de HMAC keys para Service Accounts e usuários. Um atacante pode explorar isso gerando um HMAC key para um Service Account com privilégios elevados, assim escalando privilégios no Cloud Storage. Enquanto as HMAC keys associadas a usuários são recuperáveis apenas via o web console, tanto as access e secret keys permanecem permanentemente acessíveis, permitindo o possível armazenamento de backups de acesso. Por outro lado, as HMAC keys vinculadas a Service Accounts são acessíveis via API, mas suas access e secret keys não são recuperáveis após a criação, adicionando uma camada de complexidade para acesso contínuo.

# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance

## If you have TROUBLES creating the HMAC key this was you can also do it contacting the API directly:
PROJECT_ID = '$PROJECT_ID'
TARGET_SERVICE_ACCOUNT = f"exam-storage-sa-read-flag-3@{PROJECT_ID}.iam.gserviceaccount.com"
ACCESS_TOKEN = "$CLOUDSDK_AUTH_ACCESS_TOKEN"
import requests
import json
key = requests.post(
f'https://www.googleapis.com/storage/v1/projects/{PROJECT_ID}/hmacKeys',
params={'access_token': ACCESS_TOKEN, 'serviceAccountEmail': TARGET_SERVICE_ACCOUNT}
).json()
#print(json.dumps(key, indent=4))
print(f'ID: {key["metadata"]["accessId"]}')
print(f'Secret: {key["secret"]}')


# Configure gsutil to use the HMAC key
gcloud config set pass_credentials_to_gsutil false
gsutil config -a

# Use it
gsutil ls gs://[BUCKET_NAME]

# Restore
gcloud config set pass_credentials_to_gsutil true

Outro exploit script para este método pode ser encontrado here.

storage.objects.create, storage.objects.delete = permissões de escrita do Storage

Para criar um novo objeto dentro de um bucket você precisa de storage.objects.create e, de acordo com the docs, você também precisa de storage.objects.delete para modificar um objeto existente.

Uma exploração muito comum de buckets em que você pode escrever na cloud é quando o bucket está armazenando arquivos do servidor web; você pode ser capaz de armazenar novo código que será usado pela aplicação web.

Composer

Composer é o Apache Airflow gerenciado dentro do GCP. Ele possui várias características interessantes:

  • Ele roda dentro de um GKE cluster, então o SA que o cluster usa é acessível pelo código executado dentro do Composer
  • Todos os componentes de um ambiente Composer (code of DAGs, plugins e dados) são armazenados dentro de um bucket do GCP. Se o atacante tiver permissões de leitura e escrita sobre ele, ele pode monitorar o bucket e sempre que um DAG for criado ou atualizado, enviar uma versão com backdoor de modo que o ambiente Composer irá obter do Storage a versão com backdoor.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs

Cloud Functions

  • O código do Cloud Functions é armazenado no Storage e sempre que uma nova versão é criada o código é enviado para o bucket e então o novo container é build a partir desse código. Portanto, sobrescrever o código antes de a nova versão ser construída permite fazer com que a cloud function execute código arbitrário.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions

App Engine

As versões do AppEngine geram alguns dados dentro de um bucket com o nome no formato: staging.<project-id>.appspot.com. Dentro desse bucket, é possível encontrar uma pasta chamada ae que conterá uma pasta por versão do app do AppEngine e dentro dessas pastas será possível encontrar o arquivo manifest.json. Este arquivo contém um json com todos os arquivos que devem ser usados para criar a versão específica. Além disso, é possível encontrar os nomes reais dos arquivos, a URL para eles dentro do bucket do GCP (os arquivos dentro do bucket tiveram seus nomes alterados para o hash sha1) e o hash sha1 de cada arquivo.

Note that it’s not possible to pre-takeover this bucket because GCP users aren’t authorized to generate buckets using the domain name appspot.com.

No entanto, com acesso de leitura e escrita sobre esse bucket, é possível escalar privilégios para o SA anexado à versão do App Engine monitorando o bucket e, sempre que uma mudança for realizada (nova versão), modificar a nova versão o mais rápido possível. Dessa forma, o container criado a partir desse código irá executar o código com backdoor.

O ataque mencionado pode ser realizado de várias maneiras diferentes, todas começam monitorando o bucket staging.<project-id>.appspot.com:

  • Faça upload do código completo da nova versão do AppEngine para um bucket diferente e disponível e prepare um manifest.json file with the new bucket name and sha1 hashes of them. Então, quando uma nova versão for criada dentro do bucket, você só precisa modificar o arquivo manifest.json e enviar o malicioso.
  • Faça upload de uma versão modificada do requirements.txt que irá usar dependências maliciosas e atualize o arquivo manifest.json com o novo nome do arquivo, URL e o hash dele.
  • Envie um main.py ou app.yaml modificado que irá executar o código malicioso e atualize o manifest.json com o novo nome do arquivo, URL e o hash dele.

You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-AppEngine

GCR

  • Google Container Registry armazena as imagens dentro de buckets; se você puder escrever nesses buckets você pode ser capaz de mover-se lateralmente para os ambientes que executam essas imagens.
  • O bucket usado pelo GCR terá uma URL similar a gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com (Os subdomínios de topo são especificados here).

Tip

Este serviço está depreciado, portanto esse ataque não é mais útil. Além disso, Artifact Registry, o serviço que substitui este, não armazena as imagens em buckets.

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks