diff --git a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md index f854e99cb..4f19916c4 100644 --- a/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md +++ b/src/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes/README.md @@ -49,7 +49,7 @@ verbs: ["create", "list", "get"] ``` ### Pod Create - Steal Token -Un attaquant ayant les permissions de créer un pod pourrait attacher un compte de service privilégié dans le pod et voler le jeton pour usurper l'identité du compte de service. Élevant effectivement les privilèges. +Un attaquant ayant les permissions de créer un pod pourrait attacher un compte de service privilégié dans le pod et voler le jeton pour usurper l'identité du compte de service. Cela permet d'escalader effectivement les privilèges. Exemple d'un pod qui volera le jeton du compte de service `bootstrap-signer` et l'enverra à l'attaquant : ```yaml @@ -72,7 +72,7 @@ serviceAccountName: bootstrap-signer automountServiceAccountToken: true hostNetwork: true ``` -### Création de Pod & Évasion +### Création et Évasion de Pod Les éléments suivants indiquent tous les privilèges qu'un conteneur peut avoir : @@ -125,7 +125,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos ``` #### Stealth -Vous voulez probablement être **plus furtif**. Dans les pages suivantes, vous pouvez voir ce à quoi vous pourriez accéder si vous créez un pod en n'activant que certains des privilèges mentionnés dans le modèle précédent : +Vous voulez probablement être **plus discret**. Dans les pages suivantes, vous pouvez voir ce à quoi vous pourriez accéder si vous créez un pod en n'activant que certains des privilèges mentionnés dans le modèle précédent : - **Privileged + hostPID** - **Privileged only** @@ -138,7 +138,7 @@ _Vous pouvez trouver un exemple de comment créer/abuser des configurations de p ### Pod Create - Move to cloud -Si vous pouvez **créer** un **pod** (et éventuellement un **compte de service**), vous pourriez être en mesure d'**obtenir des privilèges dans un environnement cloud** en **assignant des rôles cloud à un pod ou à un compte de service** et ensuite y accéder.\ +Si vous pouvez **créer** un **pod** (et éventuellement un **compte de service**), vous pourriez être en mesure de **obtenir des privilèges dans un environnement cloud** en **assignant des rôles cloud à un pod ou à un compte de service** et ensuite y accéder.\ De plus, si vous pouvez créer un **pod avec l'espace de noms réseau de l'hôte**, vous pouvez **voler le rôle IAM** de l'instance **node**. Pour plus d'informations, consultez : @@ -191,7 +191,7 @@ path: / **`pods/exec`** est une ressource dans kubernetes utilisée pour **exécuter des commandes dans un shell à l'intérieur d'un pod**. Cela permet de **lancer des commandes à l'intérieur des conteneurs ou d'obtenir un shell à l'intérieur**. -Par conséquent, il est possible de **rentrer dans un pod et de voler le token du SA**, ou d'entrer dans un pod privilégié, de s'échapper vers le nœud et de voler tous les tokens des pods dans le nœud et (ab)user du nœud : +Par conséquent, il est possible de **rentrer dans un pod et voler le token du SA**, ou d'entrer dans un pod privilégié, s'échapper vers le nœud et voler tous les tokens des pods dans le nœud et (ab)user du nœud : ```bash kubectl exec -it -n -- sh ``` @@ -206,7 +206,7 @@ Cette permission permet de **rediriger un port local vers un port dans le pod sp ```bash kubectl port-forward pod/mypod 5000:5000 ``` -### Hôtes Écrivable /var/log/ Évasion +### Hôtes Écrits /var/log/ Évasion Comme [**indiqué dans cette recherche**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html), si vous pouvez accéder ou créer un pod avec le **répertoire `/var/log/` des hôtes monté** dessus, vous pouvez **vous échapper du conteneur**.\ C'est essentiellement parce que lorsque le **Kube-API essaie d'obtenir les journaux** d'un conteneur (en utilisant `kubectl logs `), il **demande le fichier `0.log`** du pod en utilisant le point de terminaison `/logs/` du service **Kubelet**.\ @@ -222,7 +222,7 @@ kubectl logs escaper --tail=2 failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n" # Keep incrementing tail to exfiltrate the whole file ``` -- Si l'attaquant contrôle un principal avec les **permissions pour lire `nodes/log`**, il peut simplement créer un **symlink** dans `/host-mounted/var/log/sym` vers `/` et en **accédant à `https://:10250/logs/sym/`, il listera le système de fichiers racine** de l'hôte (changer le symlink peut fournir un accès à des fichiers). +- Si l'attaquant contrôle un principal avec les **permissions pour lire `nodes/log`**, il peut simplement créer un **symlink** dans `/host-mounted/var/log/sym` vers `/` et lorsqu'il **accède à `https://:10250/logs/sym/`, il listera le système de fichiers racine** de l'hôte (changer le symlink peut fournir un accès à des fichiers). ```bash curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/' bin @@ -313,15 +313,15 @@ curl -k -v -XGET -H "Authorization: Bearer " \ -H "Accept: application/json" \ https://:/api/v1/namespaces/kube-system/secrets/ ``` -### Lister les secrets +### Listing Secrets -La permission de **lister les secrets pourrait permettre à un attaquant de réellement lire les secrets** en accédant au point de terminaison de l'API REST : +Le droit de **lister les secrets pourrait permettre à un attaquant de réellement lire les secrets** en accédant au point de terminaison de l'API REST : ```bash curl -v -H "Authorization: Bearer " https://:/api/v1/namespaces/kube-system/secrets/ ``` ### Création et Lecture de Secrets -Il existe un type spécial de secret Kubernetes de type **kubernetes.io/service-account-token** qui stocke les jetons de compte de service. Si vous avez les permissions pour créer et lire des secrets, et que vous connaissez également le nom du compte de service, vous pouvez créer un secret comme suit et ensuite voler le jeton du compte de service de la victime à partir de celui-ci : +Il existe un type spécial de secret Kubernetes de type **kubernetes.io/service-account-token** qui stocke les jetons de compte de service. Si vous avez les autorisations pour créer et lire des secrets, et que vous connaissez également le nom du compte de service, vous pouvez créer un secret comme suit et ensuite voler le jeton du compte de service de la victime à partir de celui-ci : ```yaml apiVersion: v1 kind: Secret @@ -384,15 +384,74 @@ Notez que si vous êtes autorisé à créer et lire des secrets dans un certain ### Lecture d'un secret – force brute des ID de token -Bien qu'un attaquant en possession d'un token avec des permissions de lecture nécessite le nom exact du secret pour l'utiliser, contrairement au privilège plus large de _**lister les secrets**_, il existe encore des vulnérabilités. Les comptes de service par défaut dans le système peuvent être énumérés, chacun étant associé à un secret. Ces secrets ont une structure de nom : un préfixe statique suivi d'un token alphanumérique aléatoire de cinq caractères (excluant certains caractères) selon le [code source](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). +Bien qu'un attaquant en possession d'un token avec des permissions de lecture nécessite le nom exact du secret pour l'utiliser, contrairement au privilège plus large de _**lister les secrets**_, il existe encore des vulnérabilités. Les comptes de service par défaut dans le système peuvent être énumérés, chacun étant associé à un secret. Ces secrets ont une structure de nom : un préfixe statique suivi d'un token alphanumérique aléatoire de cinq caractères (à l'exception de certains caractères) selon le [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83). -Le token est généré à partir d'un ensemble limité de 27 caractères (`bcdfghjklmnpqrstvwxz2456789`), plutôt que de la plage alphanumérique complète. Cette limitation réduit le nombre total de combinaisons possibles à 14 348 907 (27^5). Par conséquent, un attaquant pourrait raisonnablement exécuter une attaque par force brute pour déduire le token en quelques heures, ce qui pourrait entraîner une élévation de privilèges en accédant à des comptes de service sensibles. +Le token est généré à partir d'un ensemble limité de 27 caractères (`bcdfghjklmnpqrstvwxz2456789`), plutôt que de l'ensemble alphanumérique complet. Cette limitation réduit le nombre total de combinaisons possibles à 14 348 907 (27^5). Par conséquent, un attaquant pourrait raisonnablement exécuter une attaque par force brute pour déduire le token en quelques heures, ce qui pourrait conduire à une élévation de privilèges en accédant à des comptes de service sensibles. -### Demandes de signature de certificat +### EncrpytionConfiguration en texte clair -Si vous avez les verbes **`create`** dans la ressource `certificatesigningrequests` (ou au moins dans `certificatesigningrequests/nodeClient`). Vous pouvez **créer** un nouveau CeSR d'un **nouveau nœud.** +Il est possible de trouver des clés en texte clair pour chiffrer des données au repos dans ce type d'objet comme : +```yaml +# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ -Selon la [documentation, il est possible d'approuver automatiquement ces demandes](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), donc dans ce cas, vous **n'avez pas besoin de permissions supplémentaires**. Sinon, vous devrez être en mesure d'approuver la demande, ce qui signifie mettre à jour dans `certificatesigningrequests/approval` et `approve` dans `signers` avec resourceName `/` ou `/*` +# +# CAUTION: this is an example configuration. +# Do not use this for your own cluster! +# + +apiVersion: apiserver.config.k8s.io/v1 +kind: EncryptionConfiguration +resources: +- resources: +- secrets +- configmaps +- pandas.awesome.bears.example # a custom resource API +providers: +# This configuration does not provide data confidentiality. The first +# configured provider is specifying the "identity" mechanism, which +# stores resources as plain text. +# +- identity: {} # plain text, in other words NO encryption +- aesgcm: +keys: +- name: key1 +secret: c2VjcmV0IGlzIHNlY3VyZQ== +- name: key2 +secret: dGhpcyBpcyBwYXNzd29yZA== +- aescbc: +keys: +- name: key1 +secret: c2VjcmV0IGlzIHNlY3VyZQ== +- name: key2 +secret: dGhpcyBpcyBwYXNzd29yZA== +- secretbox: +keys: +- name: key1 +secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY= +- resources: +- events +providers: +- identity: {} # do not encrypt Events even though *.* is specified below +- resources: +- '*.apps' # wildcard match requires Kubernetes 1.27 or later +providers: +- aescbc: +keys: +- name: key2 +secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg== +- resources: +- '*.*' # wildcard match requires Kubernetes 1.27 or later +providers: +- aescbc: +keys: +- name: key3 +secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== +``` +### Certificate Signing Requests + +Si vous avez le verbe **`create`** dans la ressource `certificatesigningrequests` (ou au moins dans `certificatesigningrequests/nodeClient`). Vous pouvez **create** un nouveau CeSR d'un **nouveau nœud.** + +Selon la [documentation, il est possible d'approuver automatiquement ces demandes](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/), donc dans ce cas, vous **n'avez pas besoin de permissions supplémentaires**. Sinon, vous devrez être en mesure d'approuver la demande, ce qui signifie une mise à jour dans `certificatesigningrequests/approval` et `approve` dans `signers` avec resourceName `/` ou `/*` Un **exemple de rôle** avec toutes les permissions requises est : ```yaml @@ -427,7 +486,7 @@ verbs: ``` Alors, avec le nouveau CSR de nœud approuvé, vous pouvez **abuser** des permissions spéciales des nœuds pour **voler des secrets** et **escalader des privilèges**. -Dans [**cet article**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) et [**celui-ci**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/), la configuration de GKE K8s TLS Bootstrap est configurée avec **signature automatique** et elle est abusée pour générer des identifiants d'un nouveau nœud K8s et ensuite les utiliser pour escalader des privilèges en volant des secrets.\ +Dans [**cet article**](https://www.4armed.com/blog/hacking-kubelet-on-gke/) et [**celui-ci**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/), la configuration de GKE K8s TLS Bootstrap est configurée avec **signature automatique** et elle est abusée pour générer des identifiants d'un nouveau nœud K8s, puis abuser de ceux-ci pour escalader des privilèges en volant des secrets.\ Si vous **avez les privilèges mentionnés, vous pourriez faire la même chose**. Notez que le premier exemple contourne l'erreur empêchant un nouveau nœud d'accéder aux secrets à l'intérieur des conteneurs parce qu'un **nœud ne peut accéder qu'aux secrets des conteneurs montés sur lui.** La façon de contourner cela est simplement de **créer des identifiants de nœud pour le nom du nœud où le conteneur avec les secrets intéressants est monté** (mais vérifiez juste comment le faire dans le premier article) : @@ -436,7 +495,7 @@ La façon de contourner cela est simplement de **créer des identifiants de nœu ``` ### AWS EKS aws-auth configmaps -Les principaux qui peuvent modifier **`configmaps`** dans l'espace de noms kube-system sur les clusters EKS (doivent être dans AWS) peuvent obtenir des privilèges d'administrateur de cluster en écrasant le **aws-auth** configmap.\ +Les principaux qui peuvent modifier **`configmaps`** dans l'espace de noms kube-system sur les clusters EKS (doivent être dans AWS) peuvent obtenir des privilèges d'administrateur de cluster en écrasant le configmap **aws-auth**.\ Les verbes nécessaires sont **`update`** et **`patch`**, ou **`create`** si le configmap n'a pas été créé : ```bash # Check if config map exists @@ -484,7 +543,7 @@ groups: ### CoreDNS config map -Si vous avez les permissions pour modifier le **`coredns` configmap** dans l'espace de noms `kube-system`, vous pouvez modifier les adresses auxquelles les domaines seront résolus afin de pouvoir effectuer des attaques MitM pour **voler des informations sensibles ou injecter du contenu malveillant**. +Si vous avez les permissions pour modifier le **`coredns` configmap** dans l'espace de noms `kube-system`, vous pouvez modifier les adresses que les domaines seront résolus afin de pouvoir effectuer des attaques MitM pour **voler des informations sensibles ou injecter du contenu malveillant**. Les verbes nécessaires sont **`update`** et **`patch`** sur le **`coredns`** configmap (ou tous les config maps). @@ -524,7 +583,7 @@ Une autre option est de simplement éditer le fichier en exécutant `kubectl edi ### Escalade dans GKE -Il existe **2 façons d'assigner des permissions K8s aux principaux GCP**. Dans tous les cas, le principal a également besoin de la permission **`container.clusters.get`** pour pouvoir rassembler des identifiants pour accéder au cluster, sinon vous devrez **générer votre propre fichier de configuration kubectl** (suivez le lien suivant). +Il existe **2 façons d'assigner des permissions K8s aux principaux GCP**. Dans tous les cas, le principal a également besoin de la permission **`container.clusters.get`** pour pouvoir rassembler des informations d'identification pour accéder au cluster, sinon vous devrez **générer votre propre fichier de configuration kubectl** (suivez le lien suivant). > [!WARNING] > Lorsqu'il communique avec le point de terminaison API K8s, le **jeton d'authentification GCP sera envoyé**. Ensuite, GCP, via le point de terminaison API K8s, vérifiera d'abord si le **principal** (par e-mail) **a un accès à l'intérieur du cluster**, puis il vérifiera s'il a **un accès via GCP IAM**.\ @@ -548,7 +607,7 @@ Les principaux qui peuvent **`update`** ou **`patch`** **`pods/ephemeralcontaine ### ValidatingWebhookConfigurations ou MutatingWebhookConfigurations -Les principaux avec l'un des verbes `create`, `update` ou `patch` sur `validatingwebhookconfigurations` ou `mutatingwebhookconfigurations` pourraient être en mesure de **créer l'une de ces webhookconfigurations** afin de pouvoir **escalader les privilèges**. +Les principaux avec l'un des verbes `create`, `update` ou `patch` sur `validatingwebhookconfigurations` ou `mutatingwebhookconfigurations` pourraient être en mesure de **créer l'une de ces configurations de webhook** afin de pouvoir **escalader les privilèges**. Pour un [exemple de `mutatingwebhookconfigurations`, consultez cette section de ce post](#malicious-admission-controller). @@ -582,19 +641,19 @@ kubectl delete pods -n kube-system ``` ### Services status (CVE-2020-8554) -Les principaux qui peuvent **modifier** **`services/status`** peuvent définir le champ `status.loadBalancer.ingress.ip` pour exploiter le **CVE-2020-8554 non corrigé** et lancer des **attaques MiTM contre le cluster**. La plupart des atténuations pour le CVE-2020-8554 empêchent uniquement les services ExternalIP (selon [**ceci**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). +Les principaux qui peuvent **modifier** **`services/status`** peuvent définir le champ `status.loadBalancer.ingress.ip` pour exploiter le **CVE-2020-8554 non corrigé** et lancer des **attaques MiTM contre le cluster**. La plupart des atténuations pour le CVE-2020-8554 ne préviennent que les services ExternalIP (selon [**ceci**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego)). ### Nodes and Pods status -Les principaux ayant des permissions **`update`** ou **`patch`** sur `nodes/status` ou `pods/status`, pourraient modifier des étiquettes pour affecter les contraintes de planification appliquées. +Les principaux avec des permissions **`update`** ou **`patch`** sur `nodes/status` ou `pods/status`, pourraient modifier des étiquettes pour affecter les contraintes de planification appliquées. ## Built-in Privileged Escalation Prevention -Kubernetes dispose d'un [mécanisme intégré](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) pour prévenir l'escalade de privilèges. +Kubernetes a un [mécanisme intégré](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) pour prévenir l'escalade de privilèges. -Ce système garantit que **les utilisateurs ne peuvent pas élever leurs privilèges en modifiant des rôles ou des liaisons de rôles**. L'application de cette règle se fait au niveau de l'API, fournissant une protection même lorsque l'autorisation RBAC est inactive. +Ce système garantit que **les utilisateurs ne peuvent pas élever leurs privilèges en modifiant des rôles ou des liaisons de rôles**. L'application de cette règle se fait au niveau de l'API, fournissant une protection même lorsque l'autorisateur RBAC est inactif. -La règle stipule qu'un **utilisateur ne peut créer ou mettre à jour un rôle que s'il possède toutes les permissions que le rôle comprend**. De plus, la portée des permissions existantes de l'utilisateur doit correspondre à celle du rôle qu'il tente de créer ou de modifier : soit à l'échelle du cluster pour les ClusterRoles, soit limitée au même espace de noms (ou à l'échelle du cluster) pour les Roles. +La règle stipule qu'un **utilisateur ne peut créer ou mettre à jour un rôle que s'il possède toutes les permissions que le rôle comprend**. De plus, la portée des permissions existantes de l'utilisateur doit correspondre à celle du rôle qu'il tente de créer ou de modifier : soit à l'échelle du cluster pour les ClusterRoles, soit confinée au même espace de noms (ou à l'échelle du cluster) pour les Roles. > [!WARNING] > Il existe une exception à la règle précédente. Si un principal a le **verbe `escalate`** sur **`roles`** ou **`clusterroles`**, il peut augmenter les privilèges des rôles et des clusterroles même sans avoir les permissions lui-même. @@ -602,7 +661,7 @@ La règle stipule qu'un **utilisateur ne peut créer ou mettre à jour un rôle ### **Get & Patch RoleBindings/ClusterRoleBindings** > [!CAUTION] -> **Apparemment, cette technique fonctionnait auparavant, mais selon mes tests, elle ne fonctionne plus pour la même raison expliquée dans la section précédente. Vous ne pouvez pas créer/modifier un rolebinding pour vous donner ou donner à un autre SA des privilèges si vous ne les avez pas déjà.** +> **Apparemment, cette technique a fonctionné auparavant, mais selon mes tests, elle ne fonctionne plus pour la même raison expliquée dans la section précédente. Vous ne pouvez pas créer/modifier un rolebinding pour vous donner ou donner à un autre SA des privilèges si vous ne les avez pas déjà.** Le privilège de créer des Rolebindings permet à un utilisateur de **lier des rôles à un compte de service**. Ce privilège peut potentiellement conduire à une escalade de privilèges car il **permet à l'utilisateur de lier des privilèges d'administrateur à un compte de service compromis.** diff --git a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md index 2d053c6e0..216464300 100644 --- a/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md +++ b/src/pentesting-cloud/kubernetes-security/kubernetes-network-attacks.md @@ -4,9 +4,9 @@ ## Introduction -Dans Kubernetes, il est observé qu'un comportement par défaut permet l'établissement de connexions entre **tous les conteneurs résidant sur le même nœud**. Cela s'applique indépendamment des distinctions de namespace. Une telle connectivité s'étend jusqu'à **la couche 2** (Ethernet). Par conséquent, cette configuration expose potentiellement le système à des vulnérabilités. En particulier, elle ouvre la possibilité pour un **conteneur malveillant** d'exécuter une **attaque par usurpation ARP** contre d'autres conteneurs situés sur le même nœud. Lors d'une telle attaque, le conteneur malveillant peut tromper pour intercepter ou modifier le trafic réseau destiné à d'autres conteneurs. +Dans Kubernetes, il est observé qu'un comportement par défaut permet l'établissement de connexions entre **tous les conteneurs résidant sur le même nœud**. Cela s'applique indépendamment des distinctions de namespace. Une telle connectivité s'étend jusqu'à **la couche 2** (Ethernet). Par conséquent, cette configuration expose potentiellement le système à des vulnérabilités. En particulier, elle ouvre la possibilité pour un **conteneur malveillant** d'exécuter une **attaque par spoofing ARP** contre d'autres conteneurs situés sur le même nœud. Lors d'une telle attaque, le conteneur malveillant peut tromper pour intercepter ou modifier le trafic réseau destiné à d'autres conteneurs. -Les attaques par usurpation ARP impliquent que **l'attaquant envoie des messages ARP falsifiés** (Address Resolution Protocol) sur un réseau local. Cela entraîne le lien de **l'adresse MAC de l'attaquant avec l'adresse IP d'un ordinateur ou serveur légitime sur le réseau**. Après l'exécution réussie d'une telle attaque, l'attaquant peut intercepter, modifier ou même arrêter des données en transit. L'attaque est exécutée sur la couche 2 du modèle OSI, c'est pourquoi la connectivité par défaut dans Kubernetes à cette couche soulève des préoccupations de sécurité. +Les attaques par spoofing ARP impliquent que **l'attaquant envoie des messages ARP falsifiés** (Address Resolution Protocol) sur un réseau local. Cela entraîne le lien de **l'adresse MAC de l'attaquant avec l'adresse IP d'un ordinateur ou serveur légitime sur le réseau**. Après l'exécution réussie d'une telle attaque, l'attaquant peut intercepter, modifier ou même arrêter les données en transit. L'attaque est exécutée au niveau de la couche 2 du modèle OSI, c'est pourquoi la connectivité par défaut dans Kubernetes à ce niveau soulève des préoccupations de sécurité. Dans le scénario, 4 machines vont être créées : @@ -102,7 +102,7 @@ Si vous souhaitez plus de détails sur les sujets de réseau introduits ici, con ### ARP -De manière générale, **le réseau pod-à-pod à l'intérieur du nœud** est disponible via un **pont** qui connecte tous les pods. Ce pont s'appelle “**cbr0**”. (Certains plugins réseau installeront leur propre pont.) Le **cbr0 peut également gérer ARP** (Address Resolution Protocol) résolution. Lorsqu'un paquet entrant arrive à cbr0, il peut résoudre l'adresse MAC de destination en utilisant ARP. +De manière générale, **le réseau pod-à-pod à l'intérieur du nœud** est disponible via un **pont** qui connecte tous les pods. Ce pont s'appelle “**cbr0**”. (Certains plugins réseau installeront leur propre pont.) Le **cbr0 peut également gérer la résolution ARP** (Address Resolution Protocol). Lorsqu'un paquet entrant arrive à cbr0, il peut résoudre l'adresse MAC de destination en utilisant ARP. Ce fait implique que, par défaut, **chaque pod s'exécutant dans le même nœud** sera capable de **communiquer** avec tout autre pod dans le même nœud (indépendamment de l'espace de noms) au niveau ethernet (couche 2). @@ -111,7 +111,7 @@ Ce fait implique que, par défaut, **chaque pod s'exécutant dans le même nœud ### DNS -Dans les environnements kubernetes, vous trouverez généralement 1 (ou plusieurs) **services DNS en cours d'exécution** généralement dans l'espace de noms kube-system : +Dans les environnements kubernetes, vous trouverez généralement 1 (ou plusieurs) **services DNS en cours d'exécution**, généralement dans l'espace de noms kube-system : ```bash kubectl -n kube-system describe services Name: kube-dns @@ -150,11 +150,11 @@ Par conséquent, le pod enverra les **requêtes DNS à l'adresse 10.96.0.10** qu > [!WARNING] > Cela signifie qu'une **requête DNS** d'un pod va **toujours** passer par le **pont** pour **traduire** l'**IP du service en IP de l'endpoint**, même si le serveur DNS est dans le même sous-réseau que le pod. > -> Sachant cela, et sachant que **les attaques ARP sont possibles**, un **pod** dans un nœud sera capable de **intercepter le trafic** entre **chaque pod** dans le **sous-réseau** et le **pont** et **modifier** les **réponses DNS** du serveur DNS (**DNS Spoofing**). +> Sachant cela, et sachant que des **attaques ARP sont possibles**, un **pod** dans un nœud sera capable de **intercepter le trafic** entre **chaque pod** dans le **sous-réseau** et le **pont** et **modifier** les **réponses DNS** du serveur DNS (**DNS Spoofing**). > > De plus, si le **serveur DNS** est dans le **même nœud que l'attaquant**, l'attaquant peut **intercepter toutes les requêtes DNS** de n'importe quel pod dans le cluster (entre le serveur DNS et le pont) et modifier les réponses. -## Spoofing ARP dans les pods dans le même nœud +## Spoofing ARP dans les pods dans le même Nœud Notre objectif est de **voler au moins la communication de l'ubuntu-victim au mysql**. @@ -233,11 +233,11 @@ arpspoof -t 172.17.0.9 172.17.0.10 ``` ## DNS Spoofing -Comme déjà mentionné, si vous **compromettez un pod dans le même nœud que le pod du serveur DNS**, vous pouvez **MitM** avec **ARPSpoofing** le **bridge et le pod DNS** et **modifier toutes les réponses DNS**. +Comme déjà mentionné, si vous **compromettez un pod dans le même nœud que le pod serveur DNS**, vous pouvez **MitM** avec **ARPSpoofing** le **pont et le pod DNS** et **modifier toutes les réponses DNS**. Vous avez un très bon **outil** et **tutoriel** pour tester cela dans [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/) -Dans notre scénario, **téléchargez** l'**outil** dans le pod attaquant et créez un \*\*fichier nommé `hosts` \*\* avec les **domaines** que vous souhaitez **spoof** comme : +Dans notre scénario, **téléchargez** l'**outil** dans le pod attaquant et créez un **fichier nommé `hosts`** avec les **domaines** que vous souhaitez **spoof** comme : ``` cat hosts google.com. 1.1.1.1 @@ -260,13 +260,45 @@ dig google.com google.com. 1 IN A 1.1.1.1 ``` > [!NOTE] -> Si vous essayez de créer votre propre script de spoofing DNS, si vous **modifiez simplement la réponse DNS** cela **ne fonctionnera pas**, car la **réponse** aura une **src IP** l'adresse IP du **pod** **malveillant** et **ne sera pas** **acceptée**.\ -> Vous devez générer un **nouveau paquet DNS** avec la **src IP** du **DNS** où la victime envoie la requête DNS (qui est quelque chose comme 172.16.0.2, pas 10.96.0.10, c'est l'IP du service DNS K8s et non l'IP du serveur DNS, plus d'informations à ce sujet dans l'introduction). +> Si vous essayez de créer votre propre script de spoofing DNS, si vous **modifiez simplement la réponse DNS** cela **ne** va **pas fonctionner**, car la **réponse** aura une **src IP** l'adresse IP du **pod** **malveillant** et **ne sera pas** **acceptée**.\ +> Vous devez générer un **nouveau paquet DNS** avec la **src IP** du **DNS** où la victime envoie la requête DNS (ce qui est quelque chose comme 172.16.0.2, pas 10.96.0.10, c'est l'IP du service DNS K8s et non l'IP du serveur DNS, plus à ce sujet dans l'introduction). +## DNS Spoofing via coreDNS configmap + +Un utilisateur ayant des permissions d'écriture sur le configmap `coredns` dans l'espace de noms kube-system peut modifier les réponses DNS du cluster. + +Vérifiez plus d'informations sur cette attaque dans : + +{{#ref}} +abusing-roles-clusterroles-in-kubernetes/README.md +{{/ref}} + +## Abusing exposed kubernetes management services + +Des services comme Apache NiFi, Kubeflow, Argo Workflows, Weave Scope et le tableau de bord Kubernetes sont souvent exposés soit à Internet, soit au sein du réseau Kubernetes. Un attaquant qui parvient à **trouver une plateforme utilisée pour gérer Kubernetes et y accéder** peut en abuser pour obtenir l'accès à l'API Kubernetes et effectuer des actions telles que créer de nouveaux pods, modifier des pods existants ou même les supprimer. + +## Enumerating kubernetes network policies + +Obtenez les **networkpolicies** configurées : +```bash +kubectl get networkpolicies --all-namespaces +``` +Obtenir les politiques réseau **Callico** : +```bash +kubectl get globalnetworkpolicy --all-namespaces +``` +Obtenez les politiques réseau **Cillium** : +```bash +kubectl get ciliumnetworkpolicy --all-namespaces +``` +Obtenez d'autres CRD liés aux politiques installés par votre plugin réseau ou solution de sécurité : +```bash +kubectl get crd | grep -i policy +``` ## Capturer le trafic -L'outil [**Mizu**](https://github.com/up9inc/mizu) est un visualiseur de trafic API **simple mais puissant pour Kubernetes** vous permettant de **voir toute la communication API** entre les microservices pour vous aider à déboguer et à résoudre les régressions.\ -Il installera des agents dans les pods sélectionnés et rassemblera leurs informations de trafic pour vous les montrer sur un serveur web. Cependant, vous aurez besoin de permissions K8s élevées pour cela (et ce n'est pas très discret). +L'outil [**Mizu**](https://github.com/up9inc/mizu) est un visualiseur de **trafic API pour Kubernetes** simple mais puissant, vous permettant de **voir toute la communication API** entre les microservices pour vous aider à déboguer et à résoudre les régressions.\ +Il installera des agents dans les pods sélectionnés et rassemblera leurs informations de trafic pour vous les afficher sur un serveur web. Cependant, vous aurez besoin de permissions K8s élevées pour cela (et ce n'est pas très discret). ## Références