Skip to main content

Analyse technique de la faille de configuration cloud de Capital One

Écrit par
Headshot of Josh Stella

Josh Stella

blog hero security alert purple

1 août 2019

0 minutes de lecture

Note de la rédaction

Cet article est paru à l’origine sur fugue.co. Fugue a rejoint Snyk en 2022 et constitue un élément clé de Snyk IaC.

MISE À JOUR : 26 août 2019

Depuis la publication de cet article, AWS a fait plusieurs déclarations publiques au sujet de la faille, qui éclairent quelque peu ce qui s’est probablement passé. Dans sa réponse au sénateur Ron Wyden, AWS a déclaré :

« Comme Capital One l’a expliqué dans son annonce publique, l’attaque s’est produite à cause d’une erreur de configuration au niveau applicatif d’un pare-feu installé par Capital One, aggravée par des autorisations définies par Capital One qui étaient probablement plus larges que prévu. Après avoir accédé aux ressources par le biais du pare-feu mal configuré et obtenu des autorisations plus étendues, nous pensons qu’une attaque SSRF a été utilisée (parmi les différentes méthodes par lesquelles un attaquant aurait pu accéder aux données après avoir pénétré le système via le pare-feu mal configuré). »

« Comme indiqué ci-dessus, l’attaque SSRF n’a pas été le principal facteur de cette attaque. Nous n’avons connaissance d’aucune autre compromission SSRF notable chez des clients AWS. »

On a beaucoup parlé de la probable composante SSRF de cette faille, mais comme AWS le précise, ce n’était pas le principal facteur de l’attaque. Le problème venait d’une configuration trop permissive des ressources cloud. Cet article décrit en détail certaines façons dont ces ressources ont pu être mal configurées et dont ces erreurs de configuration ont pu être exploitées.

ARTICLE ORIGINAL : 1er août 2019

Il s’agit d’une analyse technique de la manière dont la faille de Capital One a pu se produire, à partir des éléments disponibles dans la plainte pénale. Je tiens à préciser d’emblée que j’ai beaucoup de respect pour l’équipe cloud de Capital One, où j’ai des amis. L’entreprise a été pionnière dans le cloud computing, et ce qui lui est arrivé aurait pu arriver à presque n’importe qui. Je ne critique pas non plus Amazon Web Services (AWS), mon ancien employeur. AWS propose des services sécurisés et j’ai le plus grand respect pour l’entreprise. Le but de cet article est d’examiner une attaque combinant pare-feu, IAM et S3, afin d’illustrer certains des risques liés aux erreurs de configuration cloud auxquels toute organisation utilisant le cloud doit prêter attention.

Pour rédiger cet article, j’ai analysé les détails techniques de la plainte du FBI, puis formulé une hypothèse sur le déroulement possible de l’attaque. Je l’ai ensuite simulée dans mon compte de développement afin de pouvoir fournir des détails précis.

Les faits tels que nous les connaissons

La plainte du FBI et les publications de l’attaquante présumée sur les réseaux sociaux nous donnent quelques informations sur l’attaque, mais elles sont limitées. Il semble que l’attaquante ait utilisé Tor et IPredator pour masquer son identité et qu’elle ait découvert, par l’intermédiaire de ces services, un pare-feu mal configuré dans l’environnement AWS de Capital One. On ne sait pas clairement s’il s’agissait d’une attaque ciblant Capital One ou d’une attaque opportuniste après la découverte de cette mauvaise configuration.

De nombreux articles ont été consacrés aux motivations possibles et au parcours de l’attaquante. Je n’aborderai donc pas ces sujets et me concentrerai sur les détails techniques. Nous connaissons quatre éléments de l’attaque :

  • Pare-feu mal configuré

  • Accès à une instance EC2

  • Accès à S3 via un rôle IAM

  • Découverte et duplication de buckets S3.

Nous examinons chacun de ces éléments plus en détail ci-dessous.

Comment le piratage a pu se produire

Nous disposons de quelques détails, mais pas de beaucoup, et j’ai donc dû spéculer et interpréter les faits disponibles. Je signalerai clairement les passages où je formule des hypothèses au fil des étapes de l’attaque ci-dessous. Le schéma ci-dessous présente mon environnement sandbox, dans lequel j’ai simulé certains aspects de la faille de Capital One.

L’environnement comprend :

  1. un réseau VPC de base

  2. un groupe de sécurité autorisant HTTP(S) et SSH

  3. un bucket S3 privé

  4. deux rôles IAM : l’un avec accès à S3, l’autre sans

  5. une instance EC2 avec une adresse IP publique et le rôle IAM qui n’a pas accès à S3

Schéma d’infrastructure cloud montrant deux VPC connectés via des passerelles Internet, avec une instance EC2 et un bucket S3.

Mon objectif était de passer de l’accès shell à l’instance EC2 à la possibilité d’accéder aux données des buckets S3 privés et de les copier.

Avant d’examiner les différentes étapes en détail, signalons que le FBI a obtenu des informations grâce à un signalement concernant un fichier hébergé sur GitHub. Celui-ci contenait l’adresse IP d’un serveur ainsi que trois commandes :

« Capital One a déterminé que le fichier du 21 avril contenait le code de trois commandes, ainsi qu’une liste de plus de 700 dossiers ou buckets de données. » Nous allons examiner en détail chacune de ces commandes, ce qu’elles pouvaient être et la stratégie que l’attaquante a pu utiliser.

Étape 1 : pare-feu mal configuré

Selon la plainte du FBI, « une mauvaise configuration du pare-feu a permis à des commandes d’atteindre ce serveur et d’y être exécutées, donnant ainsi accès à des dossiers ou à des buckets… (III.A.10) »

Cela laisse penser que le pare-feu était externe au serveur plutôt que local, même si ce n’est pas précisé explicitement. De nombreux pare-feu virtuels sont disponibles sur AWS, mais il s’agirait généralement d’un groupe de sécurité. Il semble qu’un port à risque ait été laissé ouvert sur le type de pare-feu utilisé, ce qui a peut-être constitué la première ouverture exploitée lors de l’attaque. Il est possible qu’un port SSH ait été ouvert pour une opération de maintenance, ou que le serveur ait été oublié après des travaux de développement et ne soit plus utilisé. Autre possibilité : le serveur exécutait une application comme MongoDB ou ElasticSearch, qui nécessite un port ouvert pour fonctionner, mais qui n’aurait jamais dû être exposée à Internet via le pare-feu. Quels qu’aient été les détails, l’attaquante a trouvé un accès à l’infrastructure cloud de Capital One.

Étape 2 : accès à une instance EC2

D’après la description de l’entité compromise comme un « serveur » dans la plainte du FBI, et puisque l’attaquante a pu en extraire des identifiants IAM, il semble qu’une instance EC2 ait ensuite été compromise. Il pourrait s’agir d’une vulnérabilité de l’application ou du système d’exploitation : nous ne le savons tout simplement pas. Pour simuler l’attaque, j’ai supposé que l’attaquante avait obtenu un accès shell, mais pas un accès root à l’instance, car toutes les étapes suivantes peuvent être menées à bien avec un simple accès shell.

Étape 3 : accès à S3 via un rôle IAM

…« Capital One a déterminé que la première commande, une fois exécutée, avait récupéré les identifiants de sécurité d’un compte nommé ***-WAF-Role, qui permettait à son tour d’accéder à certains dossiers de Capital One chez le fournisseur de services cloud. (III.A.11) »

Une grande partie des opérations de cette attaque reposait sur l’accès, via un rôle IAM, à des buckets S3 privés, apparemment au moyen de commandes AWS CLI exécutées depuis le serveur compromis. La presse s’est beaucoup intéressée au nom du rôle, mais rien ne prouve que ce serveur était lui-même un WAF. Dans les environnements AWS dynamiques, il est courant de « réutiliser » des rôles IAM (ce n’est pas une très bonne pratique, mais c’est fréquent). De plus, comme nous le verrons ci-dessous, les associations de politiques peuvent être modifiées et portent souvent « Role » dans leur nom, comme dans l’exemple ci-dessous. Peut-être ce serveur était-il simplement une ressource oubliée, sans balises permettant de l’afficher dans les tableaux de bord des outils de gestion. J’ai rarement vu un compte AWS de grande taille sans ressources orphelines laissées ici ou là.

Si le serveur était lui-même un WAF et qu’il disposait intentionnellement d’un accès en lecture et en écriture aux buckets et aux objets contenant des données personnelles, il s’agissait d’une stratégie de défense naïve, pour des raisons évidentes. En particulier, une simple mauvaise configuration du pare-feu aurait suffi à contourner toutes les défenses architecturales protégeant les données sensibles. Ce n’est toutefois pas la seule explication possible de la faille, et je pense que d’autres éléments sont entrés en jeu : des fonctionnalités IAM et EC2 conçues pour offrir de la flexibilité, mais potentiellement détournées pour accorder des privilèges supplémentaires.

Puisqu’ils parlent de la « première commande », je pense qu’il est raisonnable de supposer qu’il s’agissait d’un script AWS CLI. Si l’instance EC2 avait déjà accès à S3, l’attaquante aurait simplement eu besoin d’exécuter une commande du type :

> curl http://169.254.169.254/latest/meta-data/iam/security-credentials/DemonstrationEC2Role

Cette commande récupère les identifiants temporaires IAM associés au rôle depuis les métadonnées de l’instance EC2. Voici à quoi ressemble la sortie :

{

  "Code" : "Success",

  "LastUpdated" : "2019-07-31T19:41:16Z",

  "Type" : "AWS-HMAC",

  "AccessKeyId" : "***************",

  "SecretAccessKey" : "**************************",

  "Token" : "AgoJb3JpZ2luX2VjEDQaCXVzLWVhc3QtMiJGMEQCIG9qFNkzROR8KaLKTTxaWYpxuE1J8ogMUWLF6EhddivjAiB84nwhPoUQl4IIWb5oGfXjc3QzRTP7nm/fG8ANqGnrJyrjAwit//////////Hpraage6UuR7XmrrdM09c9thue+fbUjYYGFHtiun96KrcDeZrJXwV/Dj8+pbn2Ivw0UydaC7Jj+XUkr8izWG7h/Hpraage6UuR7XmrrdM09c9thue++IaAjZPsutjIhkDEuggqriQCdA/4QwHgXFAjs0VzgFly9l29EVWMzvIncKQEIGFxofqwhMcOpN4uP7wseMctpqVfUfjumC/EisdYFUo8UaDctYObXBCk8tL/HvvMmJrF0aDYmcsaQ8Geu67X9LQk45xr/Hpraage6UuR7XmrrdM09c9thue+qy0evQBJbqmfrhg1bZktctodqOkngdyFN/CYDu3jVIyiLxH/3PmGedzkjJ+julYzunhj9i8V5ej4UIyGDU2KOORaRosLM+lFDJSZDfiihWvfXYYDDJkLX+tJel9qFYTqDcppVTcIjJO8yJQOYRBAvk32nu1mdkQMmafl+CwxMfppbsrja9c6A/c16tv/WcPrCzmJiu6yqbk+4QwHgXFAjs0VzgFly9l29EVWMzvIncKQEIGFxofqwhMcOpN4uP7wseMctpqVfUfjumC+Hpraage6UuR7XmrrdM09c9thue/9ZmdktOg6HAtI89GOP10OE2gJ0Pq4Er/+hUh/+LOmi3QSoALCitT2d09o/iCcXY/zzCT3ofqBTq1AQ5XbIYPbAZiKVyquo2M6EYqiODBNsSQLiMBJgZldv8LOhYOgIxz302gTBvSr7zl2vWrm5gEr9twKx1ApMkaMY0h1kNTgwTsBHm9hVdvidN3QhBzt3s7u2nvcGx5r+dWDkTQ3BI6fD31tdDKOtm7fZO9ziSgFu8U3o3ncAytioWYGXXtZN2FLzBtqp+mq6E8gc1lZnoCGkGApXltdJVSC2+tkXQJLYyF1Ubd00GH+QV8cxE/zr4=",

  "Expiration" : "2019-08-01T02:17:11Z"

}

Where the access key and secret access key are replaced with *'s and the token corrupted to protect the innocent.

Cela aurait suffi pour accéder aux buckets S3 et à leur contenu.

Mais il existe une autre possibilité quant à ce que faisait cette « première commande », et toute personne utilisant AWS doit en être consciente. Si le serveur compromis n’avait pas accès aux buckets S3 privés, mais disposait des autorisations nécessaires pour répertorier et associer des politiques IAM, l’attaquante aurait pu exploiter ces capacités pour rechercher des identifiants lui donnant cet accès. Les autorisations IAM n’ont souvent aucun lien avec les contrôles d’accès réseau au niveau IP et, comme les services AWS communiquent via IAM, ces rôles et politiques forment une sorte de réseau parallèle qui doit être sécurisé tout autant qu’un réseau traditionnel. Dans le cloud, IAM devient un moyen majeur de « mouvement latéral ».

La commande ci-dessous, par exemple, remplace un ensemble d’autorisations IAM par un autre :

> aws ec2 replace-iam-instance-profile-association --association-id iip-assoc-00facaf2870f3bcc9 --iam-instance-profile Name=DemonstrationEC2Role

Le résultat ci-dessous montre que j’ai bien remplacé les autorisations IAM existantes par celles de la politique DemonstrationEC2Role :

{

    "IamInstanceProfileAssociation": {

        "InstanceId": "i-0f566edb3389ac1f7",

        "State": "associated",

        "AssociationId": "iip-assoc-00facaf2870f3bcc9",

        "IamInstanceProfile": {

            "Id": "AIPA6MYZKKFJL2Y2G5UPO",

            "Arn": "arn:aws:iam::989506195794:instance-profile/DemonstrationEC2Role"

        }

    }

}

Parmi les autres commandes utiles pour ce type de recherche, citons :

> aws iam list-roles

> aws iam list-policies

> aws iam list-instance-profiles

Elles font exactement ce que leur nom indique : elles répertorient le catalogue de ressources IAM qu’un attaquant pourrait vouloir utiliser après avoir obtenu un accès shell à une instance EC2.

Dans cet exemple, j’ai remplacé un profil IAM limité par un autre doté d’autorisations S3 supplémentaires. Nous ne pouvons pas exclure que l’attaquante ait utilisé une méthode similaire lors de la faille de Capital One. Que ce soit le cas ou non, il est essentiel de garder cette capacité à l’esprit lorsque vous configurez les rôles IAM de vos instances EC2, en particulier celles accessibles depuis Internet : les autorisations IAM peuvent en effet permettre d’atteindre des ressources privées de votre environnement.

Dans les deux scénarios, l’attaquante a obtenu les identifiants nécessaires pour récupérer des informations depuis S3 et les dupliquer.

Étape 4 : découverte et duplication de buckets S3

« Capital One a déterminé que la troisième commande (la « commande de synchronisation »), une fois exécutée, avait utilisé le compte ***-WAF-Role pour extraire ou copier des données depuis les dossiers ou les buckets de l’espace de stockage de Capital One auxquels le compte ***-WAF-Role était autorisé à accéder. (III.A.11) »

Cela laisse penser que la commande AWS CLI `aws s3 sync` a été utilisée. C’est un indice supplémentaire que l’attaquante a obtenu un accès shell à l’instance EC2 et s’est servie d’AWS CLI pour exécuter ces commandes. Selon la plainte du ministère de la Justice, l’attaquante a répertorié les buckets S3 avec la deuxième commande, ce qui laisse supposer que le rôle IAM qu’elle utilisait disposait d’autorisations de listage et de lecture pour S3. Cela illustre le danger lié à un rôle IAM disposant d’autorisations S3 aussi étendues : même à ce stade, sans pouvoir découvrir les buckets cibles, l’attaquante n’aurait probablement pas pu récupérer beaucoup de données, voire aucune.

Recommandations

  1. Surveillez en permanence les groupes de sécurité trop permissifs et tout autre mécanisme d’accès autorisant 0.0.0.0/0. Vérifier les configurations au moment du provisionnement est nécessaire, mais loin d’être suffisant. L’infrastructure cloud est créée et modifiée via des API, ce qui signifie qu’elle évolue souvent au fil du temps, à mesure que différentes équipes et personnes interagissent avec elle.

  2. Appliquez le principe du moindre privilège et limitez strictement les rôles IAM aux autorisations absolument nécessaires à la fonction métier de la ressource qui les utilise. Pour S3, vous pouvez envisager des points de terminaison publics distincts pour les opérations de lecture et d’écriture, avec des rôles IAM différents qui ne peuvent pas effectuer l’autre opération. Supprimez tous les cas d’usage en production qui autorisent le listage des buckets S3, au profit de secrets partagés ou d’autres mécanismes.

  3. N’autorisez pas les instances EC2 à utiliser des rôles IAM permettant d’associer ou de remplacer des politiques de rôle dans les environnements de production.

  4. Nettoyez rigoureusement les ressources cloud inutilisées (en particulier les serveurs et les buckets S3) laissées après des travaux de développement ou de débogage en production.

  5. Intégrez la recherche de mauvaises configurations de l’infrastructure cloud à vos tests d’intrusion. Faites appel à des testeurs externes et assurez-vous qu’ils savent détecter et exploiter les mauvaises configurations cloud.