Kubernetes Pivoting to Clouds
GCP
Si vous exécutez un cluster k8s à l'intérieur de GCP, vous voudrez probablement qu'une application s'exécutant à l'intérieur du cluster ait un certain accès à GCP. Il existe 2 façons courantes de le faire :
Monter les clés GCP-SA en tant que secret
Une façon courante de donner accès à une application Kubernetes à GCP est de :
Créer un compte de service GCP
Lui attribuer les autorisations souhaitées
Télécharger une clé JSON du compte de service créé
Le monter en tant que secret à l'intérieur du pod
Définir la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pointant vers le chemin où se trouve le fichier JSON.
Par conséquent, en tant qu'attaquant, si vous compromettez un conteneur à l'intérieur d'un pod, vous devriez vérifier cette variable d'environnement et les fichiers JSON contenant les informations d'identification GCP.
Relier le JSON GSA au secret KSA
Une façon de donner accès à un GSA à un cluster GKE consiste à les lier de la manière suivante :
Créez un compte de service Kubernetes dans le même espace de noms que votre cluster GKE en utilisant la commande suivante :
Créez un Secret Kubernetes qui contient les informations d'identification du compte de service GCP auquel vous souhaitez accorder l'accès au cluster GKE. Vous pouvez le faire en utilisant l'outil en ligne de commande
gcloud
, comme le montre l'exemple suivant :
Liez le Secret Kubernetes au compte de service Kubernetes en utilisant la commande suivante :
Dans la deuxième étape, les informations d'identification du GSA ont été définies comme secret du KSA. Ensuite, si vous pouvez lire ce secret depuis l'intérieur du cluster GKE, vous pouvez escalader vers ce compte de service GCP.
Identité de charge de travail GKE
Avec l'identité de charge de travail, nous pouvons configurer un compte de service Kubernetes pour agir en tant que compte de service Google. Les pods s'exécutant avec le compte de service Kubernetes s'authentifieront automatiquement en tant que compte de service Google lorsqu'ils accéderont aux API Google Cloud.
La première série d'étapes pour activer ce comportement consiste à activer l'identité de charge de travail dans GCP (étapes) et à créer le compte de service GCP que vous souhaitez que k8s impersonne.
Activer l'identité de charge de travail sur un nouveau cluster
Créer/Mettre à jour un nouveau pool de nœuds (Les clusters Autopilot n'ont pas besoin de cela)
Créez le compte de service GCP à usurper depuis K8s avec les autorisations GCP :
Connectez-vous au cluster et créez le compte de service à utiliser
Lier le GSA avec le KSA
Exécutez un pod avec le KSA et vérifiez l'accès à GSA :
Vérifiez la commande suivante pour vous authentifier si nécessaire :
En tant qu'attaquant à l'intérieur de K8s, vous devriez rechercher des SAs avec l'annotation iam.gke.io/gcp-service-account
car cela indique que le SA peut accéder à quelque chose dans GCP. Une autre option serait d'essayer d'exploiter chaque KSA dans le cluster et de vérifier s'il a accès.
Depuis GCP, il est toujours intéressant d'énumérer les liens et de savoir quel accès vous donnez aux SAs à l'intérieur de Kubernetes.
Voici un script pour parcourir facilement toutes les définitions des pods à la recherche de cette annotation :
AWS
Kiam & Kube2IAM (IAM role for Pods)
Une façon (obsolète) de donner des rôles IAM aux Pods est d'utiliser un serveur Kiam ou Kube2IAM. Fondamentalement, vous devrez exécuter un daemonset dans votre cluster avec un type de rôle IAM privilégié. Ce daemonset sera celui qui donnera accès aux rôles IAM aux pods qui en ont besoin.
Tout d'abord, vous devez configurer quels rôles peuvent être accessibles à l'intérieur de l'espace de noms, et vous le faites avec une annotation à l'intérieur de l'objet de l'espace de noms:
Une fois que l'espace de noms est configuré avec les rôles IAM que les Pods peuvent avoir, vous pouvez indiquer le rôle souhaité sur chaque définition de pod avec quelque chose comme:
En tant qu'attaquant, si vous trouvez ces annotations dans les pods ou les espaces de noms ou si un serveur kiam/kube2iam est en cours d'exécution (probablement dans kube-system), vous pouvez usurper chaque rôle déjà utilisé par les pods et plus encore (si vous avez accès au compte AWS, énumérez les rôles).
Créer un Pod avec un rôle IAM
Le rôle IAM à indiquer doit être dans le même compte AWS que le rôle kiam/kube2iam et ce rôle doit pouvoir y accéder.
Rôle IAM pour les comptes de service K8s via OIDC
Ceci est la méthode recommandée par AWS.
Tout d'abord, vous devez créer un fournisseur OIDC pour le cluster.
Ensuite, vous créez un rôle IAM avec les autorisations requises par le compte de service (SA).
Créez une relation de confiance entre le rôle IAM et le compte de service en utilisant le nom du compte de service (ou les espaces de noms donnant accès au rôle à tous les comptes de service du namespace). La relation de confiance vérifiera principalement le nom du fournisseur OIDC, le nom du namespace et le nom du compte de service.
Enfin, créez un compte de service avec une annotation indiquant l'ARN du rôle, et les pods s'exécutant avec ce compte de service auront accès au jeton du rôle. Le jeton est écrit dans un fichier dont le chemin est spécifié dans
AWS_WEB_IDENTITY_TOKEN_FILE
(par défaut :/var/run/secrets/eks.amazonaws.com/serviceaccount/token
)
Pour obtenir aws en utilisant le jeton de /var/run/secrets/eks.amazonaws.com/serviceaccount/token
, exécutez :
En tant qu'attaquant, si vous pouvez énumérer un cluster K8s, vérifiez les comptes de service avec cette annotation pour escalader vers AWS. Pour ce faire, exécutez/créez simplement un pod en utilisant l'un des comptes de service privilégiés IAM et volez le jeton.
De plus, si vous êtes à l'intérieur d'un pod, vérifiez les variables d'environnement telles que AWS_ROLE_ARN et AWS_WEB_IDENTITY_TOKEN.
Parfois, la politique de confiance d'un rôle peut être mal configurée et au lieu de donner l'accès AssumeRole au compte de service attendu, elle le donne à tous les comptes de service. Par conséquent, si vous êtes capable d'écrire une annotation sur un compte de service contrôlé, vous pouvez accéder au rôle.
Consultez la page suivante pour plus d'informations:
Trouver des pods et des comptes de service avec des rôles IAM dans le cluster
Voici un script pour itérer facilement sur tous les pods et les définitions de comptes de service à la recherche de cette annotation :
Rôle IAM du nœud
La section précédente traitait de la façon de voler les rôles IAM avec les pods, mais notez qu'un nœud du cluster K8s va être une instance à l'intérieur du cloud. Cela signifie que le nœud a très probablement un nouveau rôle IAM que vous pouvez voler (notez que généralement tous les nœuds d'un cluster K8s auront le même rôle IAM, il peut donc ne pas être utile de vérifier chaque nœud).
Cependant, il est important de noter qu'il y a une exigence importante pour accéder au point de terminaison des métadonnées à partir du nœud, vous devez être dans le nœud (session ssh ?) ou au moins avoir le même réseau :
Voler le jeton de rôle IAM
Précédemment, nous avons discuté de la façon de joindre des rôles IAM aux Pods ou même de s'échapper vers le Node pour voler le rôle IAM auquel l'instance est attachée.
Vous pouvez utiliser le script suivant pour voler les nouvelles informations d'identification du rôle IAM sur lesquelles vous avez travaillé dur :
Références
Dernière mise à jour