AWS - S3 Unauthenticated Enum

Supporta HackTricks

S3 Public Buckets

Un bucket è considerato “pubblico” se qualsiasi 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 configurati erroneamente dando accesso sia a tutto che a tutti gli utenti autenticati in AWS in qualsiasi account (quindi a chiunque). Nota che, anche con tali configurazioni errate, alcune azioni potrebbero non essere eseguibili poiché i bucket potrebbero avere le proprie liste di controllo degli accessi (ACL).

Scopri di più sulla configurazione errata di AWS-S3 qui: http://flaws.cloud e http://flaws2.cloud/

Trovare AWS Buckets

Diversi metodi per trovare quando una pagina web utilizza AWS per archiviare alcune risorse:

Enumerazione & OSINT:

  • Utilizzando il plugin del browser wappalyzer

  • Utilizzando burp (spidering del 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 come resources.domain.com potrebbe avere il CNAME bucket.s3.amazonaws.com

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

  • Il nome del bucket e il nome del 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 verificare che sia un bucket puoi anche visitare https://flaws.cloud.s3.amazonaws.com/.

Brute-Force

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

# Genera una wordlist per creare permutazioni
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

# Genera una wordlist basata sui domini e sottodomini da testare
## Scrivi quei domini e sottodomini 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

# Crea permutazioni basate su un elenco con i domini e sottodomini da attaccare
goaltdns -l /tmp/words-hosts-s3.txt -w /tmp/words-s3.txt -o /tmp/final-words-s3.txt.temp
## Lo strumento precedente è specializzato nella creazione di permutazioni per sottodomini, filtra quell'elenco
### Rimuovi le righe che terminano con "."
cat /tmp/final-words-s3.txt.temp | grep -Ev "\.$" > /tmp/final-words-s3.txt.temp2
### Crea un elenco senza TLD
cat /tmp/final-words-s3.txt.temp2 | sed -E 's/\.[a-zA-Z0-9]+$//' > /tmp/final-words-s3.txt.temp3
### Crea un elenco senza punti
cat /tmp/final-words-s3.txt.temp3 | tr -d "." > /tmp/final-words-s3.txt.temp4http://phantom.s3.amazonaws.com/
### Crea un elenco senza trattini
cat /tmp/final-words-s3.txt.temp3 | tr "." "-" > /tmp/final-words-s3.txt.temp5

## Genera la wordlist finale
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

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

Loot S3 Buckets

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

Trova la Regione

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

Tramite 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.

Verifica 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 sarai indirizzato alla posizione corretta:

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 verificare 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, inserire solo il nome del bucket e non l'intero dominio AWSs3. Esempio: s3://<BUCKETNAME>

Modello di URL pubblico

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

Ottenere 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 sull'account limitano in base all'account in cui si trova il principale richiedente). E poiché la politica può contenere wildcard, è possibile trovare il numero dell'account 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 API Gateway URLs, Lambda URLs, Data Exchange data sets e persino per ottenere il valore dei tag (se conosci la chiave del tag). Puoi trovare maggiori informazioni nella ricerca originale e lo strumento conditional-love per automatizzare questa exploitazione.

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 è "Access Denied" significa che l'ID dell'account era sbagliato.

Utilizzo delle email per l'enumerazione dell'account root

Come spiegato in questo post del blog, è possibile verificare se un indirizzo email è collegato a un account AWS provando a concedere permessi a un'email 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