iam:PassRole : comment il fonctionne, comment les attaquants en abusent et comment le restreindre
Résumé
iam:PassRoleest la permission qu'AWS vérifie lorsqu'un principal confie un rôle IAM à un service, par exemple comme rôle d'exécution d'une fonction Lambda ou comme profil d'instance d'une instance EC2. Elle n'a pas d'appel d'API propre.- AWS n'autorise la transmission que si trois conditions sont réunies : les politiques de l'appelant autorisent
iam:PassRolesur ce rôle, la politique de confiance du rôle autorise le service cible, et le rôle se trouve dans le même compte que l'appelant. - Combiné à une permission qui crée ou met à jour des ressources de calcul,
iam:PassRolepermet à un principal d'exécuter du code avec un rôle qui ne lui a jamais été accordé. Dans la carte d'escalade de privilèges AWS de Pathbreak, 55 pour cent des chemins d'escalade de privilèges en dépendent. - CloudTrail n'enregistre aucun événement pour la transmission elle-même, la détection repose donc sur l'appel de création ou de mise à jour et sur le paramètre de requête qui porte l'ARN du rôle.
- Le correctif est un ARN de rôle précis ou un chemin IAM dans l'élément
Resource. Une conditioniam:PassedToServicesur une ressource définie par un caractère générique restreint le service, mais autorise toujours chaque rôle qui fait confiance à ce service.
iam:PassRole est la permission AWS IAM qui contrôle quels rôles un principal peut confier à un service AWS, comme le rôle d'exécution d'une fonction Lambda, le profil d'instance d'une instance EC2 ou le rôle de service d'un projet CodeBuild. C'est aussi la permission qui apparaît le plus souvent dans la carte d'escalade de privilèges AWS de Pathbreak : 55 pour cent des chemins d'escalade de privilèges de la carte en dépendent, et ces chemins atteignent 23 services AWS, parce que chaque service qui exécute des charges de travail en votre nom accepte un rôle que vous lui confiez. Il est facile de l'accorder trop largement, car une ressource définie par un caractère générique paraît inoffensive lors d'une revue de politique et la transmission elle-même n'apparaît jamais dans CloudTrail. Cet article explique ce que fait la permission, les vérifications qu'effectue AWS, comment un attaquant s'en sert, ce que montrent les journaux et comment la restreindre pour fermer le chemin.
Ce qu'est iam:PassRole
De nombreux services AWS agissent avec un rôle IAM que vous leur donnez lorsque vous configurez une ressource. Une fonction Lambda s'exécute avec son rôle d'exécution, une instance EC2 obtient des identifiants depuis son profil d'instance, et un projet CodeBuild appelle AWS avec son rôle de service. Confier ce rôle au service s'appelle transmettre le rôle, et AWS vérifie si l'appelant est autorisé à le faire.
Cette vérification, c'est iam:PassRole. La documentation AWS indique explicitement que PassRole est une permission et n'a pas d'appel d'API, il n'existe donc aucune opération PassRole dans le SDK. L'ARN du rôle circule comme paramètre d'un autre appel, par exemple le paramètre Role de l'appel Lambda CreateFunction, et le service vérifie la permission iam:PassRole de l'appelant pendant qu'il traite cet appel.
La permission existe pour empêcher un principal de confier à un service plus d'accès qu'il n'en possède lui-même. Si un développeur sans aucune permission Amazon S3 pouvait transmettre un rôle qui autorise S3, le service effectuerait ces actions S3 en son nom, ce qui est exactement l'escalade contre laquelle AWS met en garde sur la même page.
Les trois vérifications qu'effectue AWS quand un rôle est transmis
L'article du blog AWS Security consacré à PassRole énonce trois conditions qui doivent toutes être remplies avant qu'un service puisse utiliser un rôle transmis.
- L'appelant est autorisé à transmettre ce rôle. Une politique basée sur l'identité de l'appelant doit autoriser
iam:PassRoleavec le rôle dans l'élémentResource, chaque condition de cette instruction doit être remplie, et rien d'autre ne doit le refuser, y compris les politiques de contrôle de service, les limites de permissions, les politiques de session et les politiques de point de terminaison VPC. - Le rôle fait confiance au service cible. La politique de confiance du rôle doit autoriser le principal de service, par exemple
lambda.amazonaws.compour un rôle d'exécution Lambda. AWS précise que dans certains cas la ressource est tout de même créée lorsque la relation de confiance manque, mais que le service ne peut alors pas utiliser le rôle. - Le rôle et l'appelant sont dans le même compte. Le guide de l'utilisateur IAM indique que
iam:PassRolene transmet un rôle qu'à un service du même compte AWS, si bien qu'une architecture inter-comptes a besoin d'un rôle dans le second compte qui puisse endosser le premier.
Pour un attaquant, la deuxième condition définit la liste des cibles. Tout rôle du compte dont la politique de confiance nomme un service dans lequel l'attaquant peut créer des ressources est un candidat, et la première condition décide si l'attaquant peut l'utiliser.
Où a lieu la vérification PassRole
La vérification a lieu chaque fois qu'une ressource est créée avec un rôle de service, et chaque fois qu'une ressource existante est mise à jour avec un nouveau rôle. Changer le rôle d'exécution d'une fonction Lambda est une mise à jour de ce type, elle exige donc la même permission que la création de la fonction.
Les services qui utilisent des rôles liés à un service créent et gèrent généralement ces rôles eux-mêmes, si bien qu'aucune transmission n'a lieu. Lorsqu'un service vous laisse choisir un rôle lié à un service, par exemple un groupe Amazon EC2 Auto Scaling créé avec un rôle nommé, AWS vérifie iam:PassRole de la même manière.
Le tableau liste quelques appels courants qui transmettent un rôle et le paramètre de requête qui le porte. C'est ce même paramètre qu'une règle de détection doit lire.
| Service | Appel qui transmet le rôle | Paramètre qui porte le rôle | Entrée de la carte des attaques |
|---|---|---|---|
| Lambda | CreateFunction | Role | Transmettre un rôle à Lambda |
| EC2 | RunInstances | IamInstanceProfile (le profil d'instance qui contient le rôle) | Transmettre un rôle à EC2 |
| CloudFormation | CreateStack | RoleARN | Transmettre un rôle à CloudFormation |
| CodeBuild | CreateProject | serviceRole | Transmettre un rôle à CodeBuild |
La carte recense chaque transmission que Pathbreak suit, y compris les jobs Glue, les jobs d'entraînement SageMaker, les tâches ECS, Step Functions et Bedrock AgentCore, et la carte des attaques peut être filtrée sur iam:PassRole pour les voir ensemble.
Comment les attaquants abusent de iam:PassRole
iam:PassRole et lambda:CreateFunction détenus ensemble, un principal crée une fonction, lui confie un rôle privilégié, et la fonction s'exécute avec ce rôle. La transmission n'apparaît jamais dans CloudTrail comme un événement propre.L'abus suit les trois mêmes étapes, quel que soit le service concerné.
Trouver un rôle privilégié qui fait confiance à un service. iam:ListRoles renvoie la politique de confiance de chaque rôle dans le champ AssumeRolePolicyDocument, si bien qu'un seul appel montre quels rôles font confiance à Lambda, EC2, CodeBuild ou tout autre service. L'attaquant cherche un rôle aux permissions étendues dont la politique de confiance nomme un service dans lequel il peut créer des ressources.
Créer une ressource avec ce rôle attaché. Avec iam:PassRole sur le rôle et lambda:CreateFunction, l'attaquant crée une fonction dont le rôle d'exécution est le rôle privilégié. AWS accepte la transmission parce que la politique de l'appelant l'autorise et que le rôle fait confiance à lambda.amazonaws.com.
Exécuter du code avec le rôle. L'attaquant invoque la fonction, et le code qu'il a écrit s'exécute avec les permissions du rôle privilégié. Si le rôle est administrateur, une seule création et une seule invocation suffisent pour prendre le compte. La même manœuvre fonctionne via le user-data EC2, un buildspec CodeBuild, un modèle CloudFormation ou le script d'un job Glue, c'est pourquoi une seule autorisation iam:PassRole trop large peut ouvrir de nombreux chemins à la fois.
La version Lambda de cette chaîne, avec les événements CloudTrail de chaque étape, est traitée dans trois attaques d'escalade de privilèges AWS, avec les preuves CloudTrail et le correctif.
Pourquoi iam:PassedToService seul ne suffit pas
iam:PassedToService est une clé de condition qui limite le service auquel un rôle peut être transmis. Elle est utile, et la validation de politiques d'AWS elle-même émet un avertissement de sécurité pour iam:PassRole avec une ressource définie par un caractère générique, et recommande soit des ARN de rôle précis, soit cette condition. Les deux options sont pourtant loin d'être équivalentes, car la condition restreint le service alors que le caractère générique couvre toujours chaque rôle du compte.
La politique gérée AWS AWSLambda_FullAccess montre clairement l'écart. Elle accorde lambda:*, iam:ListRoles et iam:GetRole, et elle autorise iam:PassRole sur "Resource": "*" avec iam:PassedToService défini sur lambda.amazonaws.com. Un principal doté de cette politique peut lister les rôles du compte, trouver n'importe quel rôle dont la politique de confiance autorise Lambda, créer une fonction avec ce rôle et l'invoquer. Si un rôle privilégié du compte fait confiance à Lambda, la condition n'empêche en rien l'escalade, car la transmission se fait bel et bien vers Lambda.
La condition trouve son utilité lorsqu'elle est combinée à une ressource précise. Un ARN de rôle précis décide quel rôle peut être transmis, et iam:PassedToService décide à quel service il peut l'être, ce qui compte lorsqu'un rôle fait confiance à plusieurs services.
Comment détecter l'abus de iam:PassRole dans CloudTrail
AWS indique qu'aucun journal CloudTrail n'est généré pour PassRole, la preuve est donc toujours l'appel de création ou de mise à jour qui a reçu le rôle.
- Surveillez le paramètre. Pour Lambda, il s'agit de l'événement de gestion
CreateFunctionavec l'ARN du rôle dans ses paramètres de requête. La référence CloudTrail de Lambda affiche le nom de l'événement sous la formeCreateFunction20150331, une règle doit donc correspondre au préfixe du nom de l'événement. La même référence précise que les paramètresEnvironmentetZipFilesont exclus du journal, si bien que le code téléversé par l'attaquant ne figure pas dans l'événement. - Comparez le rôle à l'appelant. Le signal fort est un appel de création qui attache un rôle disposant de plus de permissions que le principal qui passe l'appel, surtout de la part d'un principal qui n'a jamais créé ce type de ressource.
- Activez les événements qui suivent. L'
InvokeLambda est un événement de données, et CloudTrail ne l'enregistre pas par défaut, comme AWS le confirme. Activer les événements de données Lambda permet à une règle d'associer la création à une invocation quelques minutes plus tard. - Lisez les échecs. CloudTrail enregistre les appels échoués avec un code d'erreur et un message d'erreur. Lorsqu'une transmission est refusée, l'erreur renvoyée par AWS nomme
iam:PassRoleet l'ARN du rôle, comme le montrent les conseils de dépannage d'AWS. Une série d'appels de création refusés qui nomment chacun un rôle différent, c'est à cela que ressemble un attaquant qui teste quels rôles il peut transmettre.
Une fois la transmission réussie, l'activité propre du rôle est le dernier endroit où regarder. Les appels d'API effectués avec le rôle transmis depuis une fonction ou une instance qui n'existait pas une heure plus tôt méritent un examen attentif.
Comment restreindre iam:PassRole
L'objectif est que chaque principal ne puisse transmettre que les rôles dont sa fonction a besoin, et uniquement aux services qui les utilisent.
- Nommez les rôles. Placez des ARN de rôle précis dans l'élément
Resource. Là où des rôles sont créés souvent, utilisez un chemin IAM commearn:aws:iam::111122223333:role/application_role/*ou un préfixe de nom, pour que les nouveaux rôles de ce chemin soient couverts sans modifier la politique, comme le recommande le blog AWS Security. - Ajoutez
iam:PassedToService. Utilisez cette condition avec une ressource précise, pour qu'un rôle qui fait confiance à plusieurs services ne puisse être transmis qu'à celui qu'utilise la charge de travail. - Utilisez
iam:AssociatedResourceArnlorsque c'est pertinent. Cette clé de condition limite la ressource à laquelle un rôle peut être attaché. Comme certains ARN de ressource changent lorsqu'une ressource est recréée, AWS indique que de nombreuses organisations restreignent plutôt qui peut modifier la ressource. - Évitez le contrôle par balises. AWS avertit que les conditions
ResourceTagsuriam:PassRolene donnent pas de résultats fiables, les balises du rôle ne sont donc pas le bon contrôle pour cette permission. - Protégez les chemins privilégiés avec une SCP. Une politique de contrôle de service peut refuser
iam:PassRolesur un chemin protégé, par exemple les rôles qu'utilise une équipe de sécurité, sauf si l'appelant porte une balise précise ou se trouve dans un chemin approuvé. - Encadrez les rôles que créent les développeurs. Si les développeurs peuvent créer leurs propres rôles, exigez une limite de permissions sur ces rôles et autorisez-les à ne transmettre que des rôles d'un chemin dédié, pour qu'un rôle qu'ils créent puis transmettent ne puisse pas dépasser la limite.
Chaque changement préserve la capacité dont l'équipe dépend et ferme les chemins qui passent par des rôles qu'elle n'a jamais eu besoin de transmettre.
Ce que la restriction de PassRole ne corrige pas
Restreindre iam:PassRole ferme les chemins qui commencent par une nouvelle ressource. Cela ne change rien pour les ressources auxquelles un rôle privilégié est déjà attaché, car modifier ce que ces ressources exécutent ne transmet jamais de rôle. Ces chemins demandent leurs propres contrôles sur les permissions de modification.
- Code de fonction Lambda.
lambda:UpdateFunctionCoderemplace le code d'une fonction existante et laisse son rôle d'exécution en place, si bien que le code de l'attaquant s'exécute avec ce rôle à la prochaine invocation de la fonction. - User-data EC2. Avec
ec2:StopInstances,ec2:ModifyInstanceAttributeetec2:StartInstances, un attaquant arrête une instance, réécrit son user-data et la redémarre. Par défaut, le user-data ne s'exécute qu'au premier démarrage, l'attaquant fournit donc une configuration cloud-init qui s'exécute à chaque démarrage, et le script s'exécute sous le profil existant de l'instance. - Commandes SSM.
ssm:SendCommandexécute un script sur une instance gérée, et ce script peut lire les identifiants du rôle déjà attaché à l'instance. - Rôles de stack CloudFormation. AWS indique qu'une fois qu'un rôle de service est attaché à une stack, les utilisateurs qui peuvent agir sur la stack peuvent utiliser le rôle, qu'ils disposent ou non de
iam:PassRole, si bien qu'un principal capable de mettre à jour la stack ou d'exécuter un change set hérite du rôle. La variante UpdateStack fonctionne de la même manière. - Projets CodeBuild. Lancer un build d'un projet existant avec un buildspec remplacé exécute les commandes de l'attaquant sous le rôle de service du projet.
Une revue de compte qui s'arrête à iam:PassRole passera à côté de tous ces cas, c'est pourquoi la carte les liste comme des entrées distinctes.
Comment vérifier qui peut transmettre un rôle privilégié
Pour un principal et un rôle, le simulateur de politiques IAM donne une réponse rapide. Il évalue les politiques basées sur l'identité et les politiques de contrôle de service, conditions comprises, pour le principal que vous désignez.
aws iam simulate-principal-policy \--policy-source-arn arn:aws:iam::111122223333:user/dev-user \--action-names iam:PassRole \--resource-arns arn:aws:iam::111122223333:role/AdminRole
Lorsque la politique du principal utilise iam:PassedToService, ajoutez un argument --context-entries qui fixe la clé iam:PassedToService au service cible, par exemple lambda.amazonaws.com, car sans lui le simulateur n'a aucune valeur à laquelle comparer. Le résultat ne répond qu'à la première des trois vérifications. Savoir si la politique de confiance du rôle autorise le service est une question distincte, à laquelle on répond en lisant l'AssumeRolePolicyDocument du rôle, et l'appelant a toujours besoin de la permission de création pour ce service. AWS précise aussi que les résultats du simulateur peuvent différer de l'environnement réel.
C'est gérable pour une seule paire, mais irréaliste sur un compte qui compte des centaines de principaux et de rôles. L'outil gratuit et open source pathbreak-audit lit l'IAM d'un compte et liste les rôles et utilisateurs qui portent des permissions exploitables et des combinaisons comme iam:PassRole avec une action de création, avec le correctif de chacune, comme point de départ. Pathbreak va plus loin en résolvant chaque transmission face aux politiques de l'appelant, aux limites, aux SCP et à la politique de confiance du rôle, si bien que seuls les chemins qui aboutiraient réellement sont signalés, classés selon ce que le rôle transmis peut atteindre.
Questions fréquentes
Que fait iam:PassRole ?
iam:PassRole est la permission qu'AWS vérifie lorsqu'un principal donne un rôle IAM à un service, par exemple comme rôle d'exécution d'une fonction Lambda ou comme profil d'instance EC2. Elle contrôle quels rôles un principal peut confier à des services, pour que le service n'agisse jamais avec plus d'accès que le principal n'était censé en avoir. Pathbreak montre quels principaux de vos comptes peuvent transmettre chaque rôle privilégié.
iam:PassRole est-il dangereux en soi ?
Pas en soi. Il devient un chemin d'escalade de privilèges lorsqu'il est combiné à une permission qui crée ou met à jour une ressource acceptant un rôle, comme lambda:CreateFunction ou ec2:RunInstances, et lorsqu'un rôle privilégié fait confiance à ce service. Restreindre l'élément Resource à des rôles précis supprime le chemin. Pathbreak vérifie la politique de confiance et les conditions de chaque transmission lorsqu'il valide un chemin.
CloudTrail enregistre-t-il iam:PassRole ?
Non. AWS documente que PassRole est une permission et ne génère aucun événement CloudTrail. La transmission apparaît comme paramètre de l'appel qui a créé ou modifié la ressource, par exemple l'ARN du rôle dans un événement Lambda CreateFunction, et les transmissions refusées apparaissent comme des appels de création échoués dont le message d'erreur nomme iam:PassRole.
iam:PassedToService suffit-il à rendre iam:PassRole sûr ?
Pas lorsque la ressource est un caractère générique. La condition limite le service, mais chaque rôle du compte qui fait confiance à ce service peut toujours être transmis, ce qui est le cas avec la politique gérée AWSLambda_FullAccess. Combinez iam:PassedToService avec des ARN de rôle précis ou un chemin IAM.
Comment savoir qui peut transmettre un rôle privilégié dans mon compte ?
Pour un seul principal, aws iam simulate-principal-policy avec iam:PassRole et l'ARN du rôle indique si les politiques du principal autorisent la transmission, et la politique de confiance du rôle montre quels services peuvent le recevoir. Sur un compte entier, pathbreak-audit liste les principaux qui détiennent ces permissions, et Pathbreak valide quelles transmissions aboutiraient et les classe selon ce qu'ils atteignent.
Découvrez quels principaux de vos comptes peuvent transmettre un rôle privilégié aujourd'hui, et le changement unique qui ferme chaque chemin.
Demander une démo Voir la démo