AWS - S3 Unauthenticated Enum

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

S3 Public Buckets

Un bucket est considéré “public” si n’importe quel utilisateur peut lister le contenu du bucket, et “private” si le contenu du bucket ne peut être listé ou écrit que par certains utilisateurs.

Les entreprises peuvent avoir des permissions des buckets mal configurées donnant accès soit à tout, soit à toute personne authentifiée dans AWS dans n’importe quel compte (donc à n’importe qui). Notez que même avec de telles mauvaises configurations certaines actions peuvent ne pas être réalisables car les buckets peuvent avoir leurs propres listes de contrôle d’accès (ACLs).

En savoir plus sur les misconfigurations AWS-S3 ici : http://flaws.cloud et http://flaws2.cloud/

Finding AWS Buckets

Différentes méthodes pour détecter quand une page web utilise AWS pour stocker des ressources :

Enumeration & OSINT:

  • Utiliser le plugin navigateur wappalyzer
  • En utilisant burp (spidering le web) ou en naviguant manuellement sur la page toutes les ressources chargées seront sauvegardées dans l’History.
  • Vérifier la présence de ressources dans des domaines tels que :
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • Vérifier les CNAMES car resources.domain.com peut avoir le CNAME bucket.s3.amazonaws.com
  • s3dns – Un serveur DNS léger qui identifie passivement les cloud storage buckets (S3, GCP, Azure) en analysant le trafic DNS. Il détecte les CNAMEs, suit les chaînes de résolution et matche les motifs de bucket, offrant une alternative tranquille au brute-force ou à la découverte via API. Parfait pour les workflows de recon et OSINT.
  • Vérifier https://buckets.grayhatwarfare.com, un site listant des buckets ouverts déjà découverts.
  • Le bucket name et le bucket domain name doivent être les mêmes.
  • flaws.cloud est à l’IP 52.92.181.107 et si vous y allez il redirige vers https://aws.amazon.com/s3/. De plus, dig -x 52.92.181.107 renvoie s3-website-us-west-2.amazonaws.com.
  • Pour vérifier que c’est un bucket vous pouvez aussi visiter https://flaws.cloud.s3.amazonaws.com/.

Brute-Force

Vous pouvez trouver des buckets en brute-forçant des noms liés à l’entreprise ciblée lors du pentesting :

# Generate a wordlist to create permutations
curl -s https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt > /tmp/words-s3.txt.temp
curl -s https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt >>/tmp/words-s3.txt.temp
cat /tmp/words-s3.txt.temp | sort -u > /tmp/words-s3.txt

# Generate a wordlist based on the domains and subdomains to test
## Write those domains and subdomains in subdomains.txt
cat subdomains.txt > /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "-" >> /tmp/words-hosts-s3.txt
cat subdomains.txt | tr "." "\n" | sort -u >> /tmp/words-hosts-s3.txt

# Create permutations based in a list with the domains and subdomains to attack
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## The previous tool is specialized increating permutations for subdomains, lets filter that list
### Remove lines ending with "."
cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### Create list without TLD
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### Create list without dots
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### Create list without hyphens
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5

## Generate the final wordlist
cat /tmp/final-words-s3.txt.temp2 /tmp/final-words-s3.txt.temp3 /tmp/final-words-s3.txt.temp4 /tmp/final-words-s3.txt.temp5 | grep -v -- "-\." | awk '{print tolower($0)}' | sort -u > /tmp/final-words-s3.txt

## Call s3scanner
s3scanner --threads 100 scan --buckets-file /tmp/final-words-s3.txt  | grep bucket_exists

Loot S3 Buckets

Pour des buckets S3 ouverts, BucketLoot peut automatiquement chercher des informations intéressantes.

Find the Region

Vous pouvez trouver toutes les régions supportées par AWS sur https://docs.aws.amazon.com/general/latest/gr/s3.html

By DNS

Vous pouvez obtenir la région d’un bucket avec un dig et nslookup en faisant une requête DNS sur l’IP découverte :

dig flaws.cloud
;; ANSWER SECTION:
flaws.cloud.    5    IN    A    52.218.192.11

nslookup 52.218.192.11
Non-authoritative answer:
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.

Vérifiez que le domaine résolu contient le mot “website”.
Vous pouvez accéder au site statique en allant sur : flaws.cloud.s3-website-us-west-2.amazonaws.com
ou vous pouvez accéder au bucket en visitant : flaws.cloud.s3-us-west-2.amazonaws.com

En essayant

Si vous essayez d’accéder à un bucket, mais que dans le nom de domaine vous spécifiez une autre région (par exemple le bucket est dans bucket.s3.amazonaws.com mais vous essayez d’accéder à bucket.s3-website-us-west-2.amazonaws.com), alors il vous sera indiqué l’emplacement correct :

Énumération du bucket

Pour tester l’ouverture du bucket, un utilisateur peut simplement entrer l’URL dans son navigateur web. Un bucket privé répondra par “Access Denied”. Un bucket public listera les 1,000 premiers objets qui ont été stockés.

Accessible à tous:

Privé:

Vous pouvez aussi vérifier cela avec le cli:

#Use --no-sign-request for check Everyones permissions
#Use --profile <PROFILE_NAME> to indicate the AWS profile(keys) that youwant to use: Check for "Any Authenticated AWS User" permissions
#--recursive if you want list recursivelyls
#Opcionally you can select the region if you now it
aws s3 ls s3://flaws.cloud/ [--no-sign-request] [--profile <PROFILE_NAME>] [ --recursive] [--region us-west-2]

Si le bucket n’a pas de nom de domaine, lorsque vous essayez de l’énumérer, mettez uniquement le nom du bucket et pas l’intégralité du domaine AWSs3. Exemple : s3://<BUCKETNAME>

Modèle d’URL publique

https://{user_provided}.s3.amazonaws.com

Obtenir l’ID de compte depuis un Bucket public

Il est possible de déterminer un compte AWS en tirant parti du nouveau S3:ResourceAccount Policy Condition Key. Cette condition restreint l’accès en fonction du S3 bucket dans lequel se trouve un compte (d’autres policies basées sur le compte restreignent en fonction du compte dans lequel se trouve le principal demandant).
Et parce que la policy peut contenir des wildcards, il est possible de trouver le numéro de compte un seul chiffre à la fois.

Cet outil automatise le processus:

# Installation
pipx install s3-account-search
pip install s3-account-search
# With a bucket
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket
# With an object
s3-account-search arn:aws:iam::123456789012:role/s3_read s3://my-bucket/path/to/object.ext

Cette technique fonctionne également avec API Gateway URLs, Lambda URLs, Data Exchange data sets et même pour obtenir la valeur des tags (si vous connaissez la clé du tag). Vous pouvez trouver plus d’informations dans le original research et l’outil conditional-love pour automatiser cette exploitation.

Confirmer qu’un bucket appartient à un compte AWS

Comme expliqué dans this blog post, si vous avez les permissions pour lister un bucket il est possible de confirmer l’accountID auquel le bucket appartient en envoyant une requête comme :

curl -X GET "[bucketname].amazonaws.com/" \
-H "x-amz-expected-bucket-owner: [correct-account-id]"

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">...</ListBucketResult>

If the error is an “Access Denied” it means that the account ID was wrong.

Utilisation des e-mails pour l’énumération des comptes root

Comme expliqué dans this blog post, il est possible de vérifier si une adresse e-mail est liée à un compte AWS en essayant d’accorder des permissions à une adresse e-mail sur un bucket S3 via les ACLs. Si cela ne déclenche pas d’erreur, cela signifie que l’adresse e-mail est un root user d’un compte AWS :

s3_client.put_bucket_acl(
Bucket=bucket_name,
AccessControlPolicy={
'Grants': [
{
'Grantee': {
'EmailAddress': 'some@emailtotest.com',
'Type': 'AmazonCustomerByEmail',
},
'Permission': 'READ'
},
],
'Owner': {
'DisplayName': 'Whatever',
'ID': 'c3d78ab5093a9ab8a5184de715d409c2ab5a0e2da66f08c2f6cc5c0bdeadbeef'
}
}
)

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks