Kubernetes Pivoting to Clouds
GCP
Se você estiver executando um cluster k8s dentro do GCP, provavelmente desejará que alguma aplicação em execução dentro do cluster tenha acesso ao GCP. Existem 2 maneiras comuns de fazer isso:
Montando chaves GCP-SA como segredo
Uma maneira comum de dar acesso a uma aplicação Kubernetes ao GCP é:
Criar uma Conta de Serviço do GCP
Vincular a ela as permissões desejadas
Baixar uma chave json da SA criada
Montá-la como um segredo dentro do pod
Definir a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS apontando para o caminho onde o json está.
Portanto, como um atacante, se comprometer um contêiner dentro de um pod, você deve verificar essa variável de ambiente e arquivos json com credenciais do GCP.
Relacionando o json do GSA ao segredo do KSA
Uma maneira de dar acesso a um GSA a um cluster GKE é vinculando-os desta forma:
Criar uma conta de serviço do Kubernetes no mesmo namespace que seu cluster GKE usando o seguinte comando:
Crie um Segredo do Kubernetes que contenha as credenciais da conta de serviço do GCP à qual deseja conceder acesso ao cluster do GKE. Você pode fazer isso usando a ferramenta de linha de comando
gcloud
, conforme mostrado no exemplo a seguir:
Vincule o Kubernetes Secret à conta de serviço do Kubernetes usando o seguinte comando:
No segundo passo, foram definidas as credenciais do GSA como segredo do KSA. Portanto, se você puder ler esse segredo de dentro do cluster GKE, você pode escalar para essa conta de serviço GCP.
Identidade de Carga de Trabalho do GKE
Com a Identidade de Carga de Trabalho, podemos configurar uma conta de serviço do Kubernetes para atuar como uma conta de serviço do Google. Pods em execução com a conta de serviço do Kubernetes serão autenticados automaticamente como a conta de serviço do Google ao acessar as APIs do Google Cloud.
A primeira série de passos para habilitar esse comportamento é ativar a Identidade de Carga de Trabalho no GCP (passos) e criar a SA do GCP que você deseja que o k8s impersonate.
Ativar a Identidade de Carga de Trabalho em um novo cluster
Criar/Atualizar um novo nodepool (clusters do Autopilot não precisam disso)
Criar a Conta de Serviço GCP para se passar por a partir do K8s com permissões GCP:
Conecte-se ao cluster e crie a conta de serviço a ser usada
Vincule o GSA com o KSA
Execute um pod com o KSA e verifique o acesso ao GSA:
Verifique o seguinte comando para autenticar, caso necessário:
Como um atacante dentro do K8s, você deve procurar por SAs com a anotação iam.gke.io/gcp-service-account
pois isso indica que o SA pode acessar algo no GCP. Outra opção seria tentar abusar de cada KSA no cluster e verificar se ele tem acesso.
Do GCP, sempre é interessante enumerar as associações e saber quais acessos você está dando para SAs dentro do Kubernetes.
Este é um script para iterar facilmente sobre todas as definições de pods procurando por aquela anotação:
AWS
Kiam & Kube2IAM (IAM role for Pods)
Uma forma (desatualizada) de atribuir Funções IAM aos Pods é usar um Kiam ou um Kube2IAM servidor. Basicamente, você precisará executar um daemonset em seu cluster com um tipo de função IAM privilegiada. Este daemonset será o responsável por conceder acesso às funções IAM aos pods que precisam.
Primeiramente, é necessário configurar quais funções podem ser acessadas dentro do namespace, e você faz isso com uma anotação dentro do objeto namespace:
Uma vez que o namespace está configurado com as funções do IAM que os Pods podem ter, você pode indicar a função desejada em cada definição de pod com algo como:
Como atacante, se você encontrar essas anotações em pods ou namespaces ou um servidor kiam/kube2iam em execução (provavelmente em kube-system), você pode se passar por qualquer função que já está sendo usada por pods e mais (se tiver acesso à conta AWS, enumere as funções).
Criar Pod com Função IAM
A função IAM a ser indicada deve estar na mesma conta da AWS que a função kiam/kube2iam e essa função deve ter permissão para acessá-la.
Função IAM para Contas de Serviço do K8s via OIDC
Este é o método recomendado pela AWS.
Primeiramente, você precisa criar um provedor OIDC para o cluster.
Em seguida, você cria uma função IAM com as permissões que a SA irá precisar.
Crie uma relação de confiança entre a função IAM e a SA nome (ou os namespaces que dão acesso à função para todas as SAs do namespace). A relação de confiança irá verificar principalmente o nome do provedor OIDC, o nome do namespace e o nome da SA.
Por fim, crie uma SA com uma anotação indicando o ARN da função, e os pods em execução com essa SA terão acesso ao token da função. O token é escrito dentro de um arquivo e o caminho é especificado em
AWS_WEB_IDENTITY_TOKEN_FILE
(padrão:/var/run/secrets/eks.amazonaws.com/serviceaccount/token
)
Para obter aws usando o token de /var/run/secrets/eks.amazonaws.com/serviceaccount/token
, execute:
Como atacante, se você puder enumerar um cluster K8s, verifique as contas de serviço com essa anotação para escalar para a AWS. Para fazer isso, basta executar/criar um pod usando uma das contas de serviço privilegiadas do IAM e roubar o token.
Além disso, se você estiver dentro de um pod, verifique as variáveis de ambiente como AWS_ROLE_ARN e AWS_WEB_IDENTITY_TOKEN.
Às vezes, a Política de Confiança de uma função pode estar mal configurada e, em vez de conceder acesso AssumeRole à conta de serviço esperada, ela concede a todas as contas de serviço. Portanto, se você for capaz de escrever uma anotação em uma conta de serviço controlada, poderá acessar a função.
Verifique a página a seguir para mais informações:
Encontrar Pods e SAs com Funções IAM no Cluster
Este é um script para iterar facilmente sobre todos os pods e definições de sas procurando por aquela anotação:
Função IAM do Node
A seção anterior foi sobre como roubar Funções IAM com pods, mas observe que um Node do cluster K8s será uma instância dentro da nuvem. Isso significa que é altamente provável que o Node tenha uma nova função IAM que você pode roubar (observe que geralmente todos os nós de um cluster K8s terão a mesma função IAM, então pode não valer a pena verificar cada nó).
No entanto, há um requisito importante para acessar o endpoint de metadados do nó, você precisa estar no nó (sessão ssh?) ou pelo menos ter a mesma rede:
Roubar Token de Função IAM
Anteriormente discutimos como anexar Funções IAM aos Pods ou até mesmo como escapar para o Node para roubar a Função IAM que a instância tem anexada a ela.
Você pode usar o seguinte script para roubar as suas novas e árduas credenciais de função IAM:
Referências
Last updated