Welcome to the Cloud - Partie 1 (AWS)

Introduction

Au cours des dernières années, les entreprises ont initié la migration d’une partie de leur système d’information vers le « Cloud ». Ce type d’environnements apporte son lot de particularités par rapport aux environnements « on-premise » rencontrés jusqu’ici.

Cet article représente le premier chapitre d’une série d’articles dédiée aux méthodes de reconnaissance pouvant être utilisées lors des tests d’intrusion afin d’élever ses privilèges au sein de l’environnement cloud ciblé. Ce premier article est consacré à AWS (Amazon Web Services). L’objectif de cette série d’articles n’est pas de dresser une liste exhaustive des différentes méthodes d’élévations de privilèges ni de détailler des scénarios d’attaques de bout en bout, mais plutôt de mettre en avant certaines méthodes employables par un attaquant ayant compromis une première instance dans de tels environnements.

AWS et ses EC2

Au sein du Cloud Service Provider (CSP) AWS, les instances de calcul sont les EC2 (pour Elastic Compute Cloud).

Pour rappel, une instance d’EC2 est un serveur virtuel hébergé au sein des infrastructures d’AWS. Ce dernier est instancié dans une zone de disponibilité (« Availability zone », un emplacement isolé au niveau électrique, réseau et connectivité dans une région AWS comme Paris (eu-west-3) ou Ohio (us-east-2)) spécifiée à la création.

Lors du déploiement d’un EC2, les paramètres suivants doivent obligatoirement être configurés :

  • Un ID de VPC (« Virtual Private Cloud ») qui permettra de connecter une interface réseau à ce réseau virtuel ;
  • Un ID de sous-réseau (« Subnet ») associé à ce VPC ;
  • Un ID d’AMI (« Amazon Machine Image ») qui correspond à la configuration du système d’exploitation (ex : Amazon Linux 2, Ubuntu Server 22.04 LTS, Windows Server 2022 Base) qui sera utilisée par l’instance et monté (par défaut) sur un EBS (« Elastic Block Store ») ;
  • Un « Security Group », qui correspond à un ensemble de règles réseau appliquées au niveau de l’instance ;
Schéma des composants impliqués dans la création d’un EC2
Schéma des composants impliqués dans la création d’un EC2

Les prochaines sections mettront en avant différentes pistes pouvant être explorées par un attaquant afin d’élever ses privilèges une fois un premier accès à un EC2 gagné. Ce premier accès peut être obtenu de nombreuses manières telles que via la divulgation d’une clé SSH ou encore au travers de la compromission d’une application exécutée sur une instance EC2.

Élévation de privilèges 101

Comme évoqué en introduction, les méthodes étudiées dans la suite de cet article traitent uniquement des spécificités relatives aux environnements Cloud. Nous n’aborderons pas les techniques d’élévations de privilèges sur les environnements « on-premise », qui dépendent du système d’exploitation et des configurations apportées à la machine ciblée.

Metadata

Les métadonnées (« metadata ») sont des données contenant des informations sur la configuration de l’instance EC2. Ces dernières sont exposées au travers du service IMDS (« Instance MetaData Service ») au travers de l’adresse IP réservée « 169.254.169.254 ». Elles sont accessibles par défaut depuis l’instance même via HTTP de la manière suivante :

Exemple de catégories de metadata accédées au travers du service IMDSv1
Exemple de catégories de metadata accédées au travers du service IMDSv1

Il est possible de forcer l’utilisation d’IMDSv2 sur une instance, ce qui complexifie notamment la post-exploitation des attaques de type SSRF en nécessitant l’utilisation d’un jeton de session pour pouvoir accéder aux metadata.

Il est également possible de désactiver complètement l’accès à ces metadata lors de la création de l’EC2 (mais également sur une instance existante).

Pour rappel, une attaque de type SSRF (Server-Side Request Forgery) est une attaque consistant à engendrer l’envoi de requêtes arbitraires par le serveur web vulnérable. L’attaquant est alors en mesure d’utiliser le serveur comme un proxy, lui permettant notamment d’extraire des fichiers, de scanner le réseau interne, mais également, dans le cas d’une application hébergée sur une instance EC2, de communiquer avec le service de metadata. Dans ce dernier cas, l’impact peut être important si l’instance profile associé à l’instance possède des droits élevés (cf. Instance Profile).

Accès aux metadata au travers du service IMDSv2
Accès aux metadata au travers du service IMDSv2

Ces metadata contiennent de nombreuses informations sur l’instance associée classées par catégorie. Par exemple :

  • iam : informations sur les droits associés à l’instance (cf. section « Instance Profile »);
  • security-groups : informations relatives au réseau (cf. section « Déplacement latéral »);
  • public-* : informations sur les données publiques de l’instance (adresse IP, nom d’hôte, clé publique…);
  • user-data : informations sur les actions exécutées lors de l’instanciation (cf. section « User Data »);
  • tags: informations sur les tags de l’instance (désactivé par défaut).

Certaines catégories peuvent ne pas être présentes si la donnée associée n’est pas définie (ex : en l’absence d’instance profile sur l’instance, la catégorie iam n’apparaitra pas).

Instance Profile

Les services AWS étant amenés à communiquer entre eux, un moyen de gérer les droits d’accès interservices est nécessaire. Afin de faciliter cette interconnexion, les instance profiles sont utilisés sur les EC2.

Pour bien comprendre le fonctionnement des instance profiles, il convient de revenir sur les mécanismes fondamentaux de la gestion des droits au sein d’un environnement AWS.

Bien qu’entrer dans le détail des différents mécanismes impliqués nécessiterait au moins un article dédié, l’idée ici est de mettre en avant les mécanismes fondamentaux nécessaires à la compréhension des instance profiles.

Le service IAM (« Identity and Access Management ») est la pierre angulaire permettant de contrôler l’accès aux différentes ressources dans AWS. Au sein de ce service, 3 ressources vont particulièrement nous intéresser:

  • Les permissions sont les unités atomiques représentant une action spécifique sur un service particulier. Ces dernières peuvent être découpées de la manière suivante : <SERVICE>:<ACTION><RESSOURCE> (ex: iam:CreateRole pour la création de rôles IAM, s3:GetObject  pour la récupération d’objets au sein d’un bucket S3);
  • Les policies sont des objets AWS définissant, au travers des permissions, les autorisations des objets sur lesquels elles sont rattachées. Il existe 6 types de policies. Dans le contexte de cet article, seules les identity-based policies nous intéresserons. Ces dernières contrôlent les actions qu’une identité (utilisateurs, rôles, etc.) peut effectuer (ou non).
  • Les roles sont des identités (au sens AWS du terme) contenant un ensemble de policies;
  • Enfin, les instance profiles sont des conteneurs de rôle IAM permettant d’attacher un rôle IAM à une instance EC2 et ainsi, de lui attribuer un ensemble de permissions.
Représentation d’un instance profile attaché à une instance EC2
Représentation d’un instance profile attaché à une instance EC2

La section suivante évoque l’intérêt des instance profiles pour un attaquant, et les méthodes permettant de sortir du contexte de l’instance EC2 afin de rebondir sur l’environnement AWS et les différents services qui le composent.

Les metadata contenant des informations sur les instance profiles, il est possible d’accéder aux informations d’authentification temporaire (ces informations sont renouvelées à intervalles réguliers et sont mises à disposition par AWS 5 minutes avant l’expiration des anciennes). Ces dernières permettent à l’instance de communiquer avec les autres services AWS avec les permissions du rôle associé. Pour récupérer ces informations d’authentification, la route suivante peut être appelée :

Format des informations d’authentification récupérables via les metadata
Format des informations d’authentification récupérables via les metadata

Note : En plus des metadata, les éléments suivants peuvent être recherchés sur le système de fichiers d’une instance EC2 afin d’identifier des informations de connexion :

  • Variables d’environnement (AWS_ACCESS_KEY et AWS_SECRET_ACCESS_KEY) ;
  • Code source applicatif ;
  • Fichiers de configuration (ex : ~/.aws/credentials, ~/.boto, ~/.fog, etc.).

Une fois ces informations récupérées, elles peuvent être réutilisées par le biais de la CLI AWS (en local via une configuration ou directement sur certains EC2 si la CLI est préconfigurée) ou des endpoints de l’API AWS. Afin d’identifier ce que peut faire le rôle associé à l’instance profile de l’instance EC2, il est crucial de récupérer le plus d’informations possibles à son sujet.

Les permissions liées au rôle peuvent être récupérées d’au moins 3 manières :

1 – En exploitant certaines permissions, qui sont particulièrement intéressantes car elles permettent de réaliser de l’introspection. En d’autres termes, elles permettent au détenteur du rôle d’identifier ses propres permissions. Les permissions suivantes font partie de celles permettant ce genre d’actions :
– iam:GetUser ;
– iam:GetUserPolicy ;
– iam:GetPolicyVersion ;
Note : Avoir uniquement ces permissions ne permet généralement pas d’identifier toutes les permissions d’un utilisateur et doivent bien souvent être combinés avec leur alter ego List (ex : iam:ListPolicies).

Il est également à noter que dans le cas où le compte AWS utilise le Default Host Management Configuration (DHMC) du service SSM, l’instance EC2 peut (dépendemment de la configuration) avoir accès à des permissions différentes de celles définies au sein de l’instance profile. Pour pouvoir utiliser ces droits, il est nécessaire d’utiliser des identifiants de connexion temporaires spécifiques liés au role défini au sein de DHMC qui peut ainsi être assumé par l’instance. Le processus pour récupérer ces identifiants est mis en avant au sein de l’article suivant: https://awsteele.com/blog/2023/02/20/a-role-for-all-your-ec2-instances.html

2 – Si les permissions du rôle de l’instance profile ne permettent pas à l’utilisateur d’identifier ses permissions, il est possible de bruteforcer les permissions du rôle. Des outils tels que enumerate-iam (https://github.com/andresriancho/enumerate-iam) permettent, en requêtant les API d’AWS, d’identifier les permissions non destructives (get*, describe* et list*) du rôle. Toutefois cette méthode présente un inconvénient (en plus de sa non-exhaustivité), qui est le bruit généré par une telle méthode. En effet, GuardDuty (le service de threat detection d’AWS) permet d’identifier facilement ce genre de comportement.

3 – Une dernière technique est de se baser, à l’aveugle, sur des permissions alternatives pouvant présenter des effets de bord intéressant pour un attaquant.

Par exemple, nous pouvons évoquer les permissions suivantes :

  • ssm:ListDocuments et ssm:GetDocument : permettent respectivement de lister et de récupérer le contenu de documents SSM. Le service SSM (pour Systems Manager) est un service AWS permettant de gérer de manière centralisée différentes ressources AWS telles que des applications ou des instances (EC2 ou « on-premise »). Or, ce service possède une fonctionnalité permettant de partager des documents avec les instances gérées via SSM. Ces documents pouvant contenir des scripts de configuration, ces derniers peuvent s’avérer intéressants au même titre que les user data (cf. section « User Data »);
  • cloudtrail:LookupEvents : permet d’accéder à l’historique des événements sur le compte AWS où l’instance profile est défini et peut donc permettre d’obtenir des informations sur les différents utilisateurs et les rôles de chacun;
  • cloudwatch:DescribeLogGroups et cloudwatch:DescribeLogStreams (notamment inclus dans le rôle AWSEC2RoleforSSM défini par AWS) : permettent d’énumérer les services utilisés au travers des journaux d’événements CloudWatch.
Exemple de groupes de logs indiquant l’utilisation du service Lambda
Exemple de groupes de logs indiquant l’utilisation du service Lambda

Une fois les permissions obtenues, en plus d’identifier celles pouvant permettre d’élever ses privilèges de manière « classique » (cf. l’excellent blog https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-privilege-escalation), il peut être intéressant de se poser les questions suivantes :

  • Est-ce que mon rôle possède des permissions sur un autre compte AWS ? (possibilité se déplacer sur un autre compte AWS) ;
  • Est-ce que mon rôle possède des droits de modification ? (possibilité d’éditer des ressources pour élever ses privilèges) ;
  • Est-ce que mon rôle possède des droits de lecture sur des données ? (possibilité d’accéder des données sensibles) ;
  • Est-ce que mon rôle a accès à d’autres services AWS spécifiques ? (possibilité de rebondir sur d’autres services pour se déplacer au sein du même compte AWS) etc.

User Data

Les metadata d’une instance EC2 permettent également de récupérer une seconde donnée intéressante du point de vue d’un attaquant: les User Data.

Ces dernières contiennent les données utilisateur voulant être transmises à l’instance lors de son déploiement. Ces User Data peuvent se présenter sous différentes formes :

  • Script shell avec la balise <script> (généralement bash sous Linux et batch sous Windows) ;
  • Script Powershell avec la balise <powershell> ;
  • Script cloud-init avec la directive #cloud-config.

Ces scripts peuvent permettre d’assurer un certain nombre de missions allant du transfert d’informations à la configuration de l’instance en passant par le déploiement d’applicatifs. L’exécution des User Data est définie par l’utilisateur et peut être déclenchée de manière unique lors de l’instanciation de l’EC2 ou bien à chaque redémarrage.

Ces User Data sont exposées au travers des metadata de l’instance et sont donc accessibles de la manière suivante :

Format des informations d’authentification récupérables via les user data
Format des informations d’authentification récupérables via les user data

Les user data peuvent permettre à un attaquant de retrouver plusieurs types d’informations sensibles, telles que :

  • Des mots de passe / secrets applicatifs;
  • Des mots de passe / secrets système;
  • Des informations sur les droits de l’instance profile en cas d’action avec la CLI AWS ;
  • Des détails sur la configuration du système et des applicatifs ;

Fichiers intéressants

Un dernier point pouvant exposer différentes informations intéressantes au sein des instances EC2 correspond aux fichiers de logs générés par les services AWS. En effet, lors du lancement d’une instance EC2 des fichiers de logs sont générés sur le système de fichiers de l’instance.

Parmi ces fichiers, on peut retrouver les fichiers suivants (il est à noter que la lecture de ces fichiers peut nécessiter des droits élevés) :

  • /var/log/cloud-init-output.log : Fichier contenant la sortie console des scripts user data (ou « C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log » sous Windows 2019) ;
  • /etc/cloud : Répertoire relatif à cloud-init contenant des détails liés à la configuration de l’instance ;
  • /var/lib/cloud : Répertoire contenant les sous-répertoires spécifiques à cloud-init.

Les user data sont copiées et executées depuis le répertoire /var/lib/cloud/instances/<INSTANCE_ID>/ et ne sont pas supprimées après exécution. Un moyen de récupérer ces user data dans le cas où les metadata sont désactivées est donc de passer par ce dossier sur le système de fichiers.

À noter que si ce dossier n’est pas supprimé avant la création d’une image à partir d’une instance EC2 contenant des User Data (Amazon Machine Images), ces dernières se retrouveront dans toutes les instances créées à partir de cet AMI.

Exemple d’informations pouvant être présentes dans les fichiers de logs 
Exemple d’informations pouvant être présentes dans les fichiers de logs

Déplacement latéral

En dehors des élévations de privilèges à proprement parler, un point intéressant à étudier lors de la phase de reconnaissance sur une instance EC2 est le réseau. En effet, par défaut, une instance sur un VPC quelconque aura accès à toutes les autres instances EC2 (avec un Security Group par défaut) des subnets (privés et publiques) de ce VPC. Cela peut donc représenter une surface d’attaque importante et un moyen de se déplacer latéralement sur le réseau.

Pour scanner de manière plus efficiente le réseau, certaines informations peuvent être récupérées à nouveau par le biais des metadata de l’instance, notamment dans la catégorie security-groups.

En effet, les Security Groups associés à l’instance agissent comme des pare-feux virtuels contenant des règles réseau (type de protocole, port, IP source, IP de destination, etc.). Si l’instance profile possède la permission ec2:DescribeSecurityGroups, alors, il est possible d’obtenir la liste de ses règles et donc de pouvoir scanner de manière plus efficace et donc, plus discrète.

Ce dernier point conclut cet article sur les techniques de reconnaissance exploitables suite à la compromission d’une instance EC2. Il existe bien entendu de nombreuses autres pistes pouvant permettre à un attaquant de rebondir sur l’environnement AWS, telles que l’utilisation des signatures d’instances ou encore l’utilisation de permissions sur des services plus exotiques.

Toutes ces techniques sont, de toute manière, amenées à évoluer au gré des nouvelles fonctionnalités apportées par AWS. Cet article visait à traiter les techniques « quick win » les plus utilisées et les plus abordables dans le cadre de cette introduction aux tests d’intrusion Cloud.

Le prochain article de cette série se focalisera sur les instances Compute Engine de GCP.

Cheatsheet

ActionCommande
Lister les catégories de metadata (IMDSv1)curl http://169.254.169.254/latest/meta-data/
Lister les catégories de metadata (IMDSv2)1. TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`

2. curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/
Récupérer le nom de l’instance profile (IMDSv1)curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<INSTANCE_PROFILE_NAME>
Récupérer les user data (IMDSv1)curl http://169.254.169.254/latest/user-data
Récupérer les informations sur l’utilisateur ou le rôle effectuant cette opérationaws sts get-caller-identity
Lister les « inline policies » attachées à un rôleaws iam list-role-policies --role-name <ROLE_NAME>
Lister les « managed policies » attachées à un rôleaws list-attached-role-policies –role-name <ROLE_NAME>
Récupérer les informations sur une « policy »aws iam get-policy --policy-arn <POLICY_ARN>
Afficher les permissions d’une « policy » pour une version donnéeaws iam get-policy-version --policy-arn <POLICY_ARN> - -version-id <POLICY_VERSION>
Lister les documents SSMaws --region <REGION> ssm list-documents
Récupérer le contenu d’un document SSMaws --region <REGION> ssm get-document --name <DOCUMENT_NAME>
Lister l’historique des événements sur le compte AWS courantaws --region <REGION> cloudtrail lookup-events
Lister les groupes de logs CloudTrailaws --region <REGION> logs describe-log-groups
Décrire le contenu des flux de logs d’un groupe spécifiqueaws --region <REGION> logs describe-log-streams --log-group-name <LOG_GROUP_NAME>
Récupérer les « Security Groups » associés à l’instancecurl http://169.254.169.254/latest/meta-data/security-groups/
Décrire les « Security Groups »aws --region <REGION> ec2 describe-security-groups

Bibliographie

Adrien Guinault

Découvrir d'autres articles

  • Welcome on cloud 2
    Cloud

    Welcome to the Cloud – Partie 2 (GCP)

    Lire l'article
  • Cloud

    L’entreprise Imperva divulgue une exposition de données sensibles de clients de la solution Incapsula/Cloud WAF

    Lire l'article
  • Cloud

    Le trafic des applications Google Cloud routé vers la Chine et la Russie

    Lire l'article