AWS - S3, Athena & Glacier Enum

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks:

S3

Amazon S3 est un service qui vous permet de stocker de grandes quantités de données.

Amazon S3 propose plusieurs options pour assurer la protection des données au repos. Les options incluent les Permissions (Politique), le Chiffrement (Côté client et côté serveur), la Versionnage du bucket et la Suppression basée sur MFA. L'utilisateur peut activer l'une de ces options pour assurer la protection des données. La réplication des données est une fonctionnalité interne d'AWS où S3 réplique automatiquement chaque objet dans toutes les zones de disponibilité et l'organisation n'a pas besoin de l'activer dans ce cas.

Avec les autorisations basées sur les ressources, vous pouvez définir des autorisations pour les sous-répertoires de votre bucket séparément.

Versionnage du bucket et suppression basée sur MFA

Lorsque le versionnage du bucket est activé, toute action tentant de modifier un fichier à l'intérieur d'un fichier générera une nouvelle version du fichier, en conservant également le contenu précédent du même. Par conséquent, cela ne remplacera pas son contenu.

De plus, la suppression basée sur MFA empêchera les versions de fichiers dans le bucket S3 d'être supprimées et empêchera également la désactivation du versionnage du bucket, de sorte qu'un attaquant ne pourra pas modifier ces fichiers.

Journaux d'accès S3

Il est possible d'activer la journalisation des accès S3 (qui est désactivée par défaut) pour un certain bucket et enregistrer les journaux dans un autre bucket pour savoir qui accède au bucket (les deux buckets doivent être dans la même région).

URL pré-signées S3

Il est possible de générer une URL pré-signée qui peut généralement être utilisée pour accéder au fichier spécifié dans le bucket. Une URL pré-signée ressemble à ceci:

https://<bucket-name>.s3.us-east-1.amazonaws.com/asd.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAUUE8GZC4S5L3TY3P%2F20230227%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230227T142551Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjELf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIBhQpdETJO3HKKDk2hjNIrPWwBE8gZaQccZFV3kCpPCWAiEAid3ueDtFFU%2FOQfUpvxYTGO%2BHoS4SWDMUrQAE0pIaB40qggMIYBAAGgwzMTgxNDIxMzg1NTMiDJLI5t7gr2EGxG1Y5CrfAioW0foHIQ074y4gvk0c%2B%2Fmqc7cNWb1njQslQkeePHkseJ3owzc%2FCwkgE0EuZTd4mw0aJciA2XIbJRCLPWTb%2FCBKPnIMJ5aBzIiA2ltsiUNQTTUxYmEgXZoJ6rFYgcodnmWW0Et4Xw59UlHnCDB2bLImxPprriyCzDDCD6nLyp3J8pFF1S8h3ZTJE7XguA8joMs4%2B2B1%2FeOZfuxXKyXPYSKQOOSbQiHUQc%2BFnOfwxleRL16prWk1t7TamvHR%2Bt3UgMn5QWzB3p8FgWwpJ6GjHLkYMJZ379tkimL1tJ7o%2BIod%2FMYrS7LDCifP9d%2FuYOhKWGhaakPuJKJh9fl%2B0vGl7kmApXigROxEWon6ms75laXebltsWwKcKuYca%2BUWu4jVJx%2BWUfI4ofoaGiCSaKALTqwu4QNBRT%2BMoK6h%2BQa7gN7JFGg322lkxRY53x27WMbUE4unn5EmI54T4dWt1%2Bg8ljDS%2BvKfBjqmAWRwuqyfwXa5YC3xxttOr3YVvR6%2BaXpzWtvNJQNnb6v0uI3%2BTtTexZkJpLQYqFcgZLQSxsXWSnf988qvASCIUhAzp2UnS1uqy7QjtD5T73zksYN2aesll7rvB80qIuujG6NOdHnRJ2M5%2FKXXNo1Yd15MtzPuSjRoSB9RSMon5jFu31OrQnA9eCUoawxbB0nHqwK8a43CKBZHhA8RoUAJW%2B48EuFsp3U%3D&X-Amz-Signature=3436e4139e84dbcf5e2e6086c0ebc92f4e1e9332b6fda24697bc339acbf2cdfa

Un URL pré-signé peut être créé à partir de la CLI en utilisant les informations d'identification d'un principal ayant accès à l'objet (si le compte que vous utilisez n'a pas accès, un URL pré-signé plus court sera créé mais il sera inutile)

aws s3 presign --region <bucket-region> 's3://<bucket-name>/<file-name>'

La seule autorisation requise pour générer une URL pré-signée est l'autorisation accordée, donc pour la commande précédente, la seule autorisation nécessaire pour le principal est s3:GetObject

Il est également possible de créer des URL pré-signées avec d'autres autorisations:

import boto3
url = boto3.client('s3').generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 'BUCKET_NAME', 'Key': 'OBJECT_KEY'},
ExpiresIn=3600
)

Mécanismes de chiffrement S3

DEK signifie Data Encryption Key et est la clé qui est toujours générée et utilisée pour chiffrer les données.

Chiffrement côté serveur avec les clés gérées par S3, SSE-S3

Cette option nécessite une configuration minimale et toute la gestion des clés de chiffrement utilisées est gérée par AWS. Tout ce que vous avez à faire est de télécharger vos données et S3 gérera tous les autres aspects. Chaque compartiment dans un compte S3 se voit attribuer une clé de compartiment.

  • Chiffrement :

  • Données d'objet + DEK en clair créé --> Données chiffrées (stockées à l'intérieur de S3)

  • DEK en clair créé + Clé maître S3 --> DEK chiffré (stocké à l'intérieur de S3) et le texte en clair est supprimé de la mémoire

  • Déchiffrement :

  • DEK chiffré + Clé maître S3 --> DEK en clair

  • DEK en clair + Données chiffrées --> Données d'objet

Veuillez noter que dans ce cas la clé est gérée par AWS (rotation uniquement tous les 3 ans). Si vous utilisez votre propre clé, vous pourrez la faire tourner, la désactiver et appliquer un contrôle d'accès.

Chiffrement côté serveur avec les clés gérées par KMS, SSE-KMS

Cette méthode permet à S3 d'utiliser le service de gestion des clés pour générer vos clés de chiffrement de données. KMS vous offre une plus grande flexibilité quant à la gestion de vos clés. Par exemple, vous pouvez désactiver, faire tourner et appliquer des contrôles d'accès à la CMK, et ordonner de s'opposer à leur utilisation en utilisant AWS Cloud Trail.

  • Chiffrement :

  • S3 demande des clés de données à KMS CMK

  • KMS utilise une CMK pour générer la paire DEK en clair et DEK chiffré et les envoie à S3

  • S3 utilise la clé en clair pour chiffrer les données, stocke les données chiffrées et la clé chiffrée et supprime de la mémoire la clé en clair

  • Déchiffrement :

  • S3 demande à KMS de déchiffrer la clé de données chiffrée de l'objet

  • KMS déchiffre la clé de données avec la CMK et la renvoie à S3

  • S3 déchiffre les données de l'objet

Chiffrement côté serveur avec des clés fournies par le client, SSE-C

Cette option vous donne la possibilité de fournir votre propre clé maître que vous pourriez déjà utiliser en dehors d'AWS. Votre clé fournie par le client serait ensuite envoyée avec vos données à S3, où S3 effectuerait alors le chiffrement pour vous.

  • Chiffrement :

  • L'utilisateur envoie les données d'objet + Clé client à S3

  • La clé client est utilisée pour chiffrer les données et les données chiffrées sont stockées

  • une valeur HMAC salée de la clé client est également stockée pour une validation future de la clé

  • la clé client est supprimée de la mémoire

  • Déchiffrement :

  • L'utilisateur envoie la clé client

  • La clé est validée par rapport à la valeur HMAC stockée

  • La clé fournie par le client est ensuite utilisée pour déchiffrer les données

Chiffrement côté client avec KMS, CSE-KMS

De manière similaire à SSE-KMS, cela utilise également le service de gestion des clés pour générer vos clés de chiffrement de données. Cependant, cette fois, KMS est sollicité par le client et non par S3. Le chiffrement a alors lieu côté client et les données chiffrées sont ensuite envoyées à S3 pour être stockées.

  • Chiffrement :

  • Le client demande une clé de données à KMS

  • KMS renvoie le DEK en clair et le DEK chiffré avec la CMK

  • Les deux clés sont renvoyées

  • Le client chiffre ensuite les données avec le DEK en clair et envoie à S3 les données chiffrées + le DEK chiffré (qui est enregistré en tant que métadonnée des données chiffrées à l'intérieur de S3)

  • Déchiffrement :

  • Les données chiffrées avec le DEK chiffré sont envoyées au client

  • Le client demande à KMS de déchiffrer la clé chiffrée en utilisant la CMK et KMS renvoie le DEK en clair

  • Le client peut maintenant déchiffrer les données chiffrées

Chiffrement côté client avec des clés fournies par le client, CSE-C

En utilisant ce mécanisme, vous pouvez utiliser vos propres clés fournies et utiliser un client AWS-SDK pour chiffrer vos données avant de les envoyer à S3 pour les stocker.

  • Chiffrement :

  • Le client génère un DEK et chiffre les données en clair

  • Ensuite, en utilisant sa propre CMK personnalisée, il chiffre le DEK

  • soumet les données chiffrées + le DEK chiffré à S3 où elles sont stockées

  • Déchiffrement :

  • S3 envoie les données chiffrées et le DEK

  • Comme le client possède déjà la CMK utilisée pour chiffrer le DEK, il déchiffre le DEK puis utilise le DEK en clair pour déchiffrer les données

Énumération

L'une des principales méthodes traditionnelles de compromission des organisations AWS commence par la compromission des compartiments accessibles publiquement. Vous pouvez trouver des énumérateurs de compartiments publics sur cette page.

# Get buckets ACLs
aws s3api get-bucket-acl --bucket <bucket-name>
aws s3api get-object-acl --bucket <bucket-name> --key flag

# Get policy
aws s3api get-bucket-policy --bucket <bucket-name>
aws s3api get-bucket-policy-status --bucket <bucket-name> #if it's public

# list S3 buckets associated with a profile
aws s3 ls
aws s3api list-buckets

# list content of bucket (no creds)
aws s3 ls s3://bucket-name --no-sign-request
aws s3 ls s3://bucket-name --recursive

# list content of bucket (with creds)
aws s3 ls s3://bucket-name
aws s3api list-objects-v2 --bucket <bucket-name>
aws s3api list-objects --bucket <bucket-name>
aws s3api list-object-versions --bucket <bucket-name>

# copy local folder to S3
aws s3 cp MyFolder s3://bucket-name --recursive

# delete
aws s3 rb s3://bucket-name –-force

# download a whole S3 bucket
aws s3 sync s3://<bucket>/ .

# move S3 bucket to different location
aws s3 sync s3://oldbucket s3://newbucket --source-region us-west-1

# list the sizes of an S3 bucket and its contents
aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"

# Update Bucket policy
aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <bucket-name>
##JSON policy example
{
"Id": "Policy1568185116930",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1568184932403",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome",
"Principal": "*"
},
{
"Sid": "Stmt1568185007451",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome/*",
"Principal": "*"
}
]
}

# Update bucket ACL
aws s3api get-bucket-acl --bucket <bucket-name> # Way 1 to get the ACL
aws s3api put-bucket-acl --bucket <bucket-name> --access-control-policy file://acl.json

aws s3api get-object-acl --bucket <bucket-name> --key flag #Way 2 to get the ACL
aws s3api put-object-acl --bucket <bucket-name> --key flag --access-control-policy file://objacl.json

##JSON ACL example
## Make sure to modify the Owner’s displayName and ID according to the Object ACL you retrieved.
{
"Owner": {
"DisplayName": "<DisplayName>",
"ID": "<ID>"
},
"Grants": [
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
},
"Permission": "FULL_CONTROL"
}
]
}
## An ACL should give you the permission WRITE_ACP to be able to put a new ACL

double pile

Vous pouvez accéder à un compartiment S3 via un point d'extrémité double pile en utilisant un nom d'extrémité de style hébergé virtuellement ou de style chemin. Ces points d'extrémité sont utiles pour accéder à S3 via IPv6.

Les points d'extrémité double pile utilisent la syntaxe suivante :

  • nom-du-compartiment.s3.dualstack.aws-region.amazonaws.com

  • s3.dualstack.aws-region.amazonaws.com/nom-du-compartiment

Élévation de privilèges

Sur la page suivante, vous pouvez vérifier comment abuser des autorisations S3 pour escalader les privilèges :

pageAWS - S3 Privesc

Accès non authentifié

pageAWS - S3 Unauthenticated Enum

Post-exploitation S3

pageAWS - S3 Post Exploitation

Persistance

pageAWS - S3 Persistence

Autres vulnérabilités S3

Problème de pollution du cache HTTP S3

Selon cette recherche, il était possible de mettre en cache la réponse d'un compartiment arbitraire comme s'il appartenait à un autre. Cela aurait pu être abusé pour modifier par exemple les réponses de fichiers JavaScript et compromettre des pages arbitraires utilisant S3 pour stocker du code statique.

Amazon Athena

Amazon Athena est un service de requête interactif qui facilite l'analyse des données directement dans le service de stockage simple d'Amazon (Amazon S3) en utilisant le SQL standard.

Vous devez préparer une table de base de données relationnelle avec le format du contenu qui va apparaître dans les compartiments S3 surveillés. Ensuite, Amazon Athena pourra peupler la base de données à partir des journaux, afin que vous puissiez interroger.

Amazon Athena prend en charge la capacité de requêter des données S3 déjà chiffrées et si configuré pour le faire, Athena peut également chiffrer les résultats de la requête qui peuvent ensuite être stockés dans S3.

Ce chiffrement des résultats est indépendant des données S3 interrogées sous-jacentes, ce qui signifie que même si les données S3 ne sont pas chiffrées, les résultats interrogés peuvent l'être. Il est important de noter qu'Amazon Athena prend en charge uniquement les données qui ont été chiffrées avec les méthodes de chiffrement S3 suivantes, SSE-S3, SSE-KMS et CSE-KMS.

SSE-C et CSE-E ne sont pas pris en charge. De plus, il est important de comprendre qu'Amazon Athena n'exécutera des requêtes que contre des objets chiffrés qui se trouvent dans la même région que la requête elle-même. Si vous devez interroger des données S3 qui ont été chiffrées à l'aide de KMS, des autorisations spécifiques sont nécessaires pour l'utilisateur Athena afin de lui permettre d'effectuer la requête.

Énumération

# Get catalogs
aws athena list-data-catalogs

# Get databases inside catalog
aws athena list-databases --catalog-name <catalog-name>
aws athena list-table-metadata --catalog-name <catalog-name> --database-name <db-name>

# Get query executions, queries and results
aws athena list-query-executions
aws athena get-query-execution --query-execution-id <id> # Get query and meta of results
aws athena get-query-results --query-execution-id <id> # This will rerun the query and get the results

# Get workgroups & Prepared statements
aws athena list-work-groups
aws athena list-prepared-statements --work-group <wg-name>
aws athena get-prepared-statement --statement-name <name> --work-group <wg-name>

# Run query
aws athena start-query-execution --query-string <query>

Références

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks:

Dernière mise à jour