AWS - S3 Unauthenticated Enum

Support HackTricks

S3 Public Buckets

Un bucket è considerato “pubblico” se qualunque utente può elencare i contenuti del bucket, e “privato” se i contenuti del bucket possono essere elencati o scritti solo da determinati utenti.

Le aziende potrebbero avere permessi dei bucket mal configurati che danno accesso sia a tutto che a chiunque sia autenticato in AWS in qualsiasi account (quindi a chiunque). Nota che, anche con tali mal configurazioni, alcune azioni potrebbero non essere eseguibili poiché i bucket potrebbero avere le proprie liste di controllo degli accessi (ACL).

Scopri di più sulle mal configurazioni di AWS-S3 qui: http://flaws.cloud e http://flaws2.cloud/

Finding AWS Buckets

Metodi diversi per trovare quando una pagina web utilizza AWS per memorizzare alcune risorse:

Enumeration & OSINT:

  • Utilizzando il plugin per browser wappalyzer

  • Utilizzando burp (spidering il web) o navigando manualmente attraverso la pagina, tutte le risorse caricate verranno salvate nella Cronologia.

  • Controlla le risorse in domini come:

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
  • Controlla i CNAMES poiché resources.domain.com potrebbe avere il CNAME bucket.s3.amazonaws.com

  • Controlla https://buckets.grayhatwarfare.com, un sito web con già bucket aperti scoperti.

  • Il nome del bucket e il nome di dominio del bucket devono essere gli stessi.

  • flaws.cloud è in IP 52.92.181.107 e se ci vai ti reindirizza a https://aws.amazon.com/s3/. Inoltre, dig -x 52.92.181.107 restituisce s3-website-us-west-2.amazonaws.com.

  • Per controllare se è un bucket puoi anche visitare https://flaws.cloud.s3.amazonaws.com/.

Brute-Force

Puoi trovare bucket forzando i nomi relativi all'azienda che stai testando:

# 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

Date le S3 open buckets, BucketLoot può automaticamente cercare informazioni interessanti.

Find the Region

Puoi trovare tutte le regioni supportate da AWS in https://docs.aws.amazon.com/general/latest/gr/s3.html

By DNS

Puoi ottenere la regione di un bucket con un dig e nslookup facendo una richiesta DNS dell'IP scoperto:

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.

Controlla che il dominio risolto contenga la parola "website". Puoi accedere al sito web statico andando su: flaws.cloud.s3-website-us-west-2.amazonaws.com oppure puoi accedere al bucket visitando: flaws.cloud.s3-us-west-2.amazonaws.com

Provando

Se provi ad accedere a un bucket, ma nel nome del dominio specifichi un'altra regione (ad esempio il bucket è in bucket.s3.amazonaws.com ma provi ad accedere a bucket.s3-website-us-west-2.amazonaws.com, allora ti verrà indicato il luogo corretto:

Enumerare il bucket

Per testare l'apertura del bucket, un utente può semplicemente inserire l'URL nel proprio browser web. Un bucket privato risponderà con "Access Denied". Un bucket pubblico elencherà i primi 1.000 oggetti che sono stati memorizzati.

Aperto a tutti:

Privato:

Puoi anche controllare questo con il 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]

Se il bucket non ha un nome di dominio, quando si tenta di enumerarlo, inserisci solo il nome del bucket e non l'intero dominio AWSs3. Esempio: s3://<BUCKETNAME>

Modello di URL pubblico

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

Ottieni l'ID dell'account da un Bucket pubblico

È possibile determinare un account AWS sfruttando il nuovo S3:ResourceAccount Policy Condition Key. Questa condizione limita l'accesso in base al bucket S3 in cui si trova un account (altre politiche basate su account limitano in base all'account in cui si trova il principale richiedente). E poiché la politica può contenere caratteri jolly, è possibile trovare il numero dell'account solo un numero alla volta.

Questo strumento automatizza il processo:

# 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

Questa tecnica funziona anche con gli URL di API Gateway, gli URL di Lambda, i set di dati di Data Exchange e persino per ottenere il valore dei tag (se conosci la chiave del tag). Puoi trovare ulteriori informazioni nella ricerca originale e nello strumento conditional-love per automatizzare questa sfruttamento.

Confermare che un bucket appartiene a un account AWS

Come spiegato in questo post del blog, se hai i permessi per elencare un bucket è possibile confermare un accountID a cui appartiene il bucket inviando una richiesta come:

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>

Se l'errore è un "Access Denied", significa che l'ID dell'account era errato.

Utilizzo di email come enumerazione dell'account root

Come spiegato in questo post del blog, è possibile verificare se un indirizzo email è associato a un qualsiasi account AWS provando a concedere a un'email permessi su un bucket S3 tramite ACL. Se questo non genera un errore, significa che l'email è un utente root di qualche account 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'
}
}
)

Riferimenti

Supporta HackTricks

Last updated