As we are "root" on the master node, let's steal the "admin.conf" file containing the authentication data for the privileged user "kunernetes-admin".
Solution
cat /etc/kubernetes/admin.conf
2. Steal Secrets
Let's use the "admin.conf" file with kubectl in order to steal all k8s secrets.
Hint
Use the kubectl "--kubeconfig" flag.
Solution
kubectl --kubeconfig=/etc/kubernetes/admin.conf get secrets -A
kubectl --kubeconfig=/etc/kubernetes/admin.conf get secret <SECRET> -o yaml
Note: Replace <SECRET> with a valid secret name.
3. Steal ETCD
There are 2 main ways to steal information from ETCD:
Read the ETCD DB files directly
Solution
Identify the ETCD DB file location via the "data-dir" parameter in the ETCD command:
Use strings as a quick and dirty way to get information from the DB file:
We can also use more advanced grep parsing to get specific info (e.g. Service Account tokens saved as secrets):
Steal the ETCD client, peer and/or server key-certificate pairs and a tool such as etcdctl in order read ETCD information via the ETCD server
Hint
Certificates and keys can be found at:
/etc/kubernetes/pki/apiserver-etcd-client.key and .crt
/etc/kubernetes/pki/etcd/peer.key and .crt
/etc/kubernetes/pki/etcd/server.key and .crt
Solution
Get etcdctl:
Use etcdctl with key-cert pair:
4. Steal Kubernetes Private Key
Let's steal the k8s private key.
Hint
Key can be found at /etc/kubernetes/pki/sa.key
Solution
Ok, we got the key. It's a ... nice souvenir? As the key is used to sign all service account JWTs let's write a python/bash/etc. script that will use it to sign our own JWTs, for any SA, that will never expire.
Hint
Required information for a valid JWT:
Service Account Name
UID
Namespace
Solution
Python script create_jwt.py:
Get all required information for creating a JWT for the "default" SA:
Execute the python script creating a token for "default" and test it:
Note: Replace <UID> with the valid UID of the default user.
Cool, now let's try to generate a token for the "cronjob-controller" SA and see how we can exploit it's privileges.
Hint
Let's leverage the "create" access on the "jobs.batch".
Hint
What if "bad pod" did a "bad job".
Solution
cron.yml:
Note: Replace <HOST> and <PORT> with the valid HOST-PORT pair pointing to your netcat listener.
Don't forget to start the listener:
Get all required information for creating a JWT for the "kube-system:cronjob-controller" SA:
Add/Uncomment the following line to the python script:
Execute the python script creating a token for "kube-system:cronjob-controller" and test it:
Reverse shell should be sent back by the malicious job pod in less then a minute.