Trouver le privesc IAM : PassRole + élévation Lambda
Le défi
Cette politique IAM AWS semble banale, mais une permission permet à son détenteur de confier un rôle puissant à une Lambda qu'il crée et exécute - passant d'un accès limité à administrateur. Lisez la politique et tapez la permission exacte qui rend cette élévation possible.
Ce que tu vas apprendre
- Reconnaître iam:PassRole sur Resource * comme un vecteur d'élévation de privilèges
- Retracer comment CreateFunction + InvokeFunction + PassRole s'enchaînent pour obtenir un accès admin
- Distinguer les statements bien restreints et inoffensifs d'un statement dangereux
- Expliquer pourquoi passer un rôle est plus puissant qu'il n'y paraît
- Nommer la restriction correcte : un ARN de Resource précis plus une condition PassedToService
Compétences testées
Prérequis
- Comment sont structurées les politiques IAM AWS (Statement, Action, Resource)
- Ce qu'est un rôle IAM et comment Lambda l'assume
- Lecture basique de JSON
Comment ça marche
Sur AWS, la puissance d'un principal ne vient pas seulement de ce qu'il peut faire directement, mais de ce qu'il peut faire faire à d'autres services en son nom. iam:PassRole est la permission de confier un rôle IAM existant à un service que l'on configure. Seule, elle ne fait rien, mais combinée à un service qui exécute du code sous un rôle transmis, elle devient l'un des vecteurs d'élévation de privilèges cloud les plus connus.
Le statement DeployLambdas accorde lambda:CreateFunction, lambda:InvokeFunction et iam:PassRole sur Resource: "*". Ce joker est le point fatal : il signifie que l'utilisateur peut passer n'importe quel rôle du compte. Un attaquant crée une Lambda, utilise iam:PassRole pour attacher un rôle à hauts privilèges (par exemple avec AdministratorAccess) comme rôle d'exécution de la fonction, puis invoque la fonction. Le code qu'elle contient s'exécute alors avec les permissions de ce rôle : l'attaquant exécute désormais des actions arbitraires en tant qu'administrateur, alors qu'il était parti d'une identité de développeur limitée.
Les deux autres statements sont des leurres bien construits : des métriques CloudWatch et Logs en lecture seule, et un accès en lecture/écriture à un unique bucket S3 nommé. Ils sont restreints et inoffensifs. Le réflexe d'audit consiste à remarquer que le privesc ne vient d'aucune action Lambda isolée, mais de l'iam:PassRole qui permet à une fonction créée d'hériter d'un rôle puissant. La réponse est iam:PassRole.
Erreurs fréquentes
- Nommer uniquement lambda:CreateFunction. Créer une fonction est inoffensif sans la capacité d'y attacher un rôle puissant.
- Choisir lambda:InvokeFunction. Exécuter une fonction que vous contrôlez déjà n'est pas une élévation en soi.
- Signaler les statements en lecture seule ou S3. Ils sont restreints à des ressources précises et n'offrent aucune élévation.
- Passer à côté du Resource: * sur PassRole. Le joker est ce qui permet à l'utilisateur de passer n'importe quel rôle ; un ARN précis fermerait la faille.
Comment s'en protéger
N'accordez jamais iam:PassRole sur Resource: "*". Restreignez précisément quels rôles peuvent être passés et à quel service, afin qu'une fonction créée ne puisse jamais s'exécuter qu'avec un rôle à moindre privilège.
- Limitez
iam:PassRoleaux ARN de rôles dont l'utilisateur a réellement besoin. - Ajoutez une
Conditionaveciam:PassedToService(par exemplelambda.amazonaws.com) pour que le rôle ne puisse pas être détourné vers un autre service. - Séparez autant que possible la permission de créer/invoquer des fonctions de celle de passer des rôles.
- Exécutez access-analyzer / IAM policy linting en CI pour repérer les
PassRoleavec des ressources en joker.