AWS - S3 Unauthenticated Enum

Reading time: 9 minutes

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 :

bash
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:

bash
#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:

bash
# 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 :

bash
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 :

python
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