# AWS - S3 Unauthenticated Enum

{{#include ../../../../banners/hacktricks-training.md}}

## S3 - Buckets pubblici

Un bucket è considerato **“public”** se **qualunque utente può elencare il contenuto** del bucket, e **“private”** se il contenuto del bucket può **essere elencato o scritto solo da determinati utenti**.

Le aziende potrebbero avere **permessi del bucket mal configurati** concedendo accesso oppure a tutto o a chiunque autenticato in AWS in qualsiasi account (quindi a chiunque). Nota che, anche con tali configurazioni errate, alcune azioni potrebbero non essere eseguibili perché i bucket possono avere le proprie ACL (access control list).

**Learn about AWS-S3 misconfiguration here:** [**http://flaws.cloud**](http://flaws.cloud/) **and** [**http://flaws2.cloud/**](http://flaws2.cloud)

### Trovare i bucket AWS

Diversi metodi per scoprire quando una pagina web usa AWS per conservare alcune risorse:

#### Enumeration & OSINT:

- Utilizzare il plugin browser **wappalyzer**
- Usare burp (**spidering** del sito) o navigando manualmente nella pagina tutte le **risorse** **caricate** saranno salvate nella History.
- **Controllare le risorse** in domini come:

```
http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/
```

- Controllare i **CNAME** poiché `resources.domain.com` potrebbe avere il CNAME `bucket.s3.amazonaws.com`
- **[s3dns](https://github.com/olizimmermann/s3dns)** – Un DNS server leggero che identifica passivamente cloud storage buckets (S3, GCP, Azure) analizzando il traffico DNS. Rileva CNAME, segue catene di risoluzione e rileva pattern di bucket, offrendo un'alternativa silenziosa al brute-force o alla scoperta tramite API. Perfetto per workflow di recon e OSINT.
- Controllare [https://buckets.grayhatwarfare.com](https://buckets.grayhatwarfare.com/), un sito con bucket aperti già **scoperti**.
- Il **nome del bucket** e il **nome del dominio del bucket** devono essere **uguali.**
- **flaws.cloud** è su **IP** 52.92.181.107 e se ci vai ti reindirizza a [https://aws.amazon.com/s3/](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/](https://flaws.cloud.s3.amazonaws.com/).

#### Brute-Force

Puoi trovare bucket effettuando **brute-force sui nomi** correlati all'azienda che stai pentestando:

- [https://github.com/sa7mon/S3Scanner](https://github.com/sa7mon/S3Scanner)
- [https://github.com/clario-tech/s3-inspector](https://github.com/clario-tech/s3-inspector)
- [https://github.com/jordanpotti/AWSBucketDump](https://github.com/jordanpotti/AWSBucketDump) (Contiene una lista con possibili nomi di bucket)
- [https://github.com/fellchase/flumberboozle/tree/master/flumberbuckets](https://github.com/fellchase/flumberboozle/tree/master/flumberbuckets)
- [https://github.com/smaranchand/bucky](https://github.com/smaranchand/bucky)
- [https://github.com/tomdev/teh_s3_bucketeers](https://github.com/tomdev/teh_s3_bucketeers)
- [https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/s3](https://github.com/RhinoSecurityLabs/Security-Research/tree/master/tools/aws-pentest-tools/s3)
- [https://github.com/Eilonh/s3crets_scanner](https://github.com/Eilonh/s3crets_scanner)
- [https://github.com/belane/CloudHunter](https://github.com/belane/CloudHunter)

<pre class="language-bash"><code class="lang-bash"># 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
<strong>### Remove lines ending with "."
</strong>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
</code></pre>

#### Loot S3 Buckets

Dato un bucket S3 aperto, [**BucketLoot**](https://github.com/redhuntlabs/BucketLoot) può automaticamente **cercare informazioni interessanti**.

### Trovare la Region

Puoi trovare tutte le region supportate da AWS su [**https://docs.aws.amazon.com/general/latest/gr/s3.html**](https://docs.aws.amazon.com/general/latest/gr/s3.html)

#### By DNS

Puoi ottenere la region di un bucket con un **`dig`** e **`nslookup`** facendo una richiesta DNS sull'IP scoperto:
```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.
```
Verifica che il dominio risolto abbia la parola "website".\
Puoi accedere allo static website 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 di dominio specifichi un'altra regione** (per 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**:

![](<../../../images/image (106).png>)

### Enumerating the bucket

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

Open to everyone:

![](<../../../images/image (201).png>)

Private:

![](<../../../images/image (83).png>)

Puoi anche verificarlo usando la 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]
```
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
```
### Ottieni l'ID account da un Bucket pubblico

È possibile determinare un account AWS sfruttando la nuova **`S3:ResourceAccount`** **chiave di condizione della policy**. Questa condizione **limita l'accesso in base al bucket S3** in cui è presente un account (altre policy basate sull'account limitano in base all'account in cui si trova il principal che effettua la richiesta).\  
E poiché la policy può contenere **wildcards**, è possibile trovare il numero dell'account **una cifra alla volta**.

Questo tool automatizza il processo:
```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
```
Questa tecnica funziona anche con API Gateway URLs, Lambda URLs, Data Exchange data sets e persino per ottenere il valore dei tags (se conosci la tag key). Puoi trovare più informazioni nella [**original research**](https://blog.plerion.com/conditional-love-for-aws-metadata-enumeration/) e nello strumento [**conditional-love**](https://github.com/plerionhq/conditional-love/) per automatizzare questo sfruttamento.

### Confermare che un bucket appartiene a un account AWS

Come spiegato in [**this blog post**](https://blog.plerion.com/things-you-wish-you-didnt-need-to-know-about-s3/)**, se hai i permessi per elencare il contenuto di un bucket** è possibile confermare l'accountID a cui il bucket appartiene inviando una richiesta come:
```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>
```
Se l'errore è “Access Denied” significa che l'ID dell'account era sbagliato.

### Email usate per root account enumeration

Come spiegato in [**this blog post**](https://blog.plerion.com/things-you-wish-you-didnt-need-to-know-about-s3/), è possibile verificare se un indirizzo email è collegato a un account AWS provando a **concedere permessi a un'email** su un S3 bucket tramite ACLs. Se questo non genera un errore, significa che l'email è un root user di qualche account 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'
}
}
)
```
## Riferimenti

- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
- [https://cloudar.be/awsblog/finding-the-account-id-of-any-public-s3-bucket/](https://cloudar.be/awsblog/finding-the-account-id-of-any-public-s3-bucket/)

{{#include ../../../../banners/hacktricks-training.md}}
