# AWS - S3, Athena & Glacier Enum

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

## S3

Amazon S3 è un servizio che permette di **memorizzare grandi quantità di dati**.

Amazon S3 fornisce più opzioni per ottenere la **protezione** dei dati a riposo. Le opzioni includono **Permission** (Policy), **Encryption** (Client e Server Side), **Bucket Versioning** e **MFA** **based delete**. L'**utente può abilitare** una qualsiasi di queste opzioni per ottenere la protezione dei dati. La **Data replication** è una funzionalità interna di AWS in cui **S3 automaticamente replica ogni oggetto su tutte le Availability Zones** e l'organizzazione non deve abilitarla in questo caso.

Con resource-based permissions, puoi definire permessi separati per le sottodirectory del tuo bucket.

### Bucket Versioning and MFA based delete

Quando Bucket Versioning è abilitato, qualsiasi azione che tenta di alterare un file genererà una nuova versione del file, mantenendo anche il contenuto precedente. Pertanto, non sovrascriverà il contenuto.

Inoltre, MFA based delete impedirà che le versioni dei file nel bucket S3 vengano cancellate e impedirà la disabilitazione di Bucket Versioning, quindi un attaccante non sarà in grado di alterare questi file.

### S3 Access logs

È possibile **abilitare S3 access login** (che di default è disabilitato) su un bucket e salvare i log in un bucket diverso per sapere chi sta accedendo al bucket (entrambi i bucket devono essere nella stessa regione).

### S3 Presigned URLs

È possibile generare una presigned URL che di solito può essere usata per **accedere al file specificato** nel bucket. Una **presigned URL looks like this**:
```
https://<bucket-name>.s3.us-east-1.amazonaws.com/asd.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAUUE8GZC4S5L3TY3P%2F20230227%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230227T142551Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjELf%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIBhQpdETJO3HKKDk2hjNIrPWwBE8gZaQccZFV3kCpPCWAiEAid3ueDtFFU%2FOQfUpvxYTGO%2BHoS4SWDMUrQAE0pIaB40qggMIYBAAGgwzMTgxNDIxMzg1NTMiDJLI5t7gr2EGxG1Y5CrfAioW0foHIQ074y4gvk0c%2B%2Fmqc7cNWb1njQslQkeePHkseJ3owzc%2FCwkgE0EuZTd4mw0aJciA2XIbJRCLPWTb%2FCBKPnIMJ5aBzIiA2ltsiUNQTTUxYmEgXZoJ6rFYgcodnmWW0Et4Xw59UlHnCDB2bLImxPprriyCzDDCD6nLyp3J8pFF1S8h3ZTJE7XguA8joMs4%2B2B1%2FeOZfuxXKyXPYSKQOOSbQiHUQc%2BFnOfwxleRL16prWk1t7TamvHR%2Bt3UgMn5QWzB3p8FgWwpJ6GjHLkYMJZ379tkimL1tJ7o%2BIod%2FMYrS7LDCifP9d%2FuYOhKWGhaakPuJKJh9fl%2B0vGl7kmApXigROxEWon6ms75laXebltsWwKcKuYca%2BUWu4jVJx%2BWUfI4ofoaGiCSaKALTqwu4QNBRT%2BMoK6h%2BQa7gN7JFGg322lkxRY53x27WMbUE4unn5EmI54T4dWt1%2Bg8ljDS%2BvKfBjqmAWRwuqyfwXa5YC3xxttOr3YVvR6%2BaXpzWtvNJQNnb6v0uI3%2BTtTexZkJpLQYqFcgZLQSxsXWSnf988qvASCIUhAzp2UnS1uqy7QjtD5T73zksYN2aesll7rvB80qIuujG6NOdHnRJ2M5%2FKXXNo1Yd15MtzPuSjRoSB9RSMon5jFu31OrQnA9eCUoawxbB0nHqwK8a43CKBZHhA8RoUAJW%2B48EuFsp3U%3D&X-Amz-Signature=3436e4139e84dbcf5e2e6086c0ebc92f4e1e9332b6fda24697bc339acbf2cdfa
```
Una presigned URL può essere **creata from the cli using credentials of a principal with access to the object** (se l'account che usi non ha accesso, verrà creata una presigned URL più corta ma sarà inutile)
```bash
aws s3 presign --region <bucket-region> 's3://<bucket-name>/<file-name>'
```
> [!NOTE]
> L'unico permesso richiesto per generare una presigned URL è il permesso che viene concesso, quindi per il comando precedente l'unico permesso necessario per il principal è `s3:GetObject`

È anche possibile creare presigned URLs con **altri permessi**:
```python
import boto3
url = boto3.client('s3').generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 'BUCKET_NAME', 'Key': 'OBJECT_KEY'},
ExpiresIn=3600
)
```
### S3 Encryption Mechanisms

**DEK significa Data Encryption Key (chiave di crittografia dei dati)** ed è la chiave che viene sempre generata e usata per cifrare i dati.

<details>

<summary><strong>Server-side encryption with S3 managed keys, SSE-S3</strong></summary>

Questa opzione richiede una configurazione minima e tutta la gestione delle chiavi di cifratura è gestita da AWS. Tutto quello che devi fare è **caricare i tuoi dati e S3 si occuperà di tutti gli altri aspetti**. A ogni bucket in un account S3 viene assegnata una bucket key.

- Encryption:
- Object Data + created plaintext DEK --> Encrypted data (stored inside S3)
- Created plaintext DEK + S3 Master Key --> Encrypted DEK (stored inside S3) and plain text is deleted from memory
- Decryption:
- Encrypted DEK + S3 Master Key --> Plaintext DEK
- Plaintext DEK + Encrypted data --> Object Data

Si noti che in questo caso **la chiave è gestita da AWS** (rotazione solo ogni 3 anni). Se usi la tua chiave potrai ruotarla, disabilitarla e applicare controlli di accesso.

</details>

<details>

<summary><strong>Server-side encryption with KMS managed keys, SSE-KMS</strong></summary>

Questo metodo permette a S3 di utilizzare il Key Management Service per generare i tuoi data encryption key. KMS ti dà una maggiore flessibilità su come le tue chiavi sono gestite. Per esempio, puoi disabilitare, ruotare e applicare controlli di accesso alla CMK, e verificare il loro utilizzo tramite AWS Cloud Trail.

- Encryption:
- S3 richiede delle data keys a KMS CMK
- KMS usa una CMK per generare la coppia DEK plaintext e DEK encrypted e le invia a S3
- S3 usa la DEK in plaintext per cifrare i dati, salva i dati cifrati e la chiave cifrata e cancella dalla memoria la chiave in chiaro
- Decryption:
- S3 chiede a KMS di decrittare la data key cifrata dell'oggetto
- KMS decripta la data key con la CMK e la invia a S3
- S3 decripta i dati dell'oggetto

</details>

<details>

<summary><strong>Server-side encryption with customer provided keys, SSE-C</strong></summary>

Questa opzione ti dà la possibilità di fornire la tua master key che potresti già usare al di fuori di AWS. La chiave fornita dal cliente verrebbe inviata con i tuoi dati a S3, dove S3 eseguirebbe la cifratura per te.

- Encryption:
- L'utente invia i dati dell'oggetto + customer key a S3
- La customer key viene usata per cifrare i dati e i dati cifrati vengono salvati
- viene memorizzato anche un valore HMAC salato della customer key per future validazioni della chiave
- la customer key viene cancellata dalla memoria
- Decryption:
- L'utente invia la customer key
- La chiave viene validata confrontandola con il valore HMAC memorizzato
- La chiave fornita dal cliente viene quindi usata per decriptare i dati

</details>

<details>

<summary><strong>Client-side encryption with KMS, CSE-KMS</strong></summary>

Analogamente a SSE-KMS, questo utilizza il KMS per generare le data encryption key. Tuttavia, questa volta KMS viene invocato dal client e non da S3. La cifratura avviene lato client e i dati cifrati vengono poi inviati a S3 per l'archiviazione.

- Encryption:
- Il client richiede una data key a KMS
- KMS restituisce la DEK in plaintext e la DEK cifrata con la CMK
- Entrambe le chiavi vengono restituite al client
- Il client cifra i dati con la DEK in plaintext e invia a S3 i dati cifrati + la DEK cifrata (che viene salvata come metadata dei dati cifrati in S3)
- Decryption:
- I dati cifrati con la DEK cifrata vengono inviati al client
- Il client chiede a KMS di decriptare la DEK cifrata usando la CMK e KMS restituisce la DEK in plaintext
- Il client può ora decriptare i dati cifrati

</details>

<details>

<summary><strong>Client-side encryption with customer provided keys, CSE-C</strong></summary>

Con questo meccanismo puoi utilizzare le tue chiavi fornite e usare un client AWS-SDK per cifrare i tuoi dati prima di inviarli a S3 per l'archiviazione.

- Encryption:
- Il client genera una DEK e cifra i dati in chiaro
- Poi, usando la propria CMK personalizzata, cifra la DEK
- invia i dati cifrati + la DEK cifrata a S3 dove vengono memorizzati
- Decryption:
- S3 invia i dati cifrati e la DEK cifrata
- Poiché il client possiede già la CMK usata per cifrare la DEK, la decripta e poi usa la DEK in plaintext per decriptare i dati

</details>

### **Enumeration**

Uno dei modi principali, tradizionalmente, per compromettere organizzazioni AWS inizia compromettendo bucket accessibili pubblicamente. **You can find** [**public buckets enumerators in this page**](../aws-unauthenticated-enum-access/index.html#s3-buckets)**.**
```bash
# Get buckets ACLs
aws s3api get-bucket-acl --bucket <bucket-name>
aws s3api get-object-acl --bucket <bucket-name> --key flag

# Get policy
aws s3api get-bucket-policy --bucket <bucket-name>
aws s3api get-bucket-policy-status --bucket <bucket-name> #if it's public

# list S3 buckets associated with a profile
aws s3 ls
aws s3api list-buckets

# list content of bucket (no creds)
aws s3 ls s3://bucket-name --no-sign-request
aws s3 ls s3://bucket-name --recursive --no-sign-request

# list content of bucket (with creds)
aws s3 ls s3://bucket-name
aws s3api list-objects-v2 --bucket <bucket-name>
aws s3api list-objects --bucket <bucket-name>
aws s3api list-object-versions --bucket <bucket-name>

# copy local folder to S3
aws s3 cp MyFolder s3://bucket-name --recursive

# delete
aws s3 rb s3://bucket-name –-force

# download a whole S3 bucket
aws s3 sync s3://<bucket>/ .

# move S3 bucket to different location
aws s3 sync s3://oldbucket s3://newbucket --source-region us-west-1

# list the sizes of an S3 bucket and its contents
aws s3api list-objects --bucket BUCKETNAME --output json --query "[sum(Contents[].Size), length(Contents[])]"

# Update Bucket policy
aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <bucket-name>
##JSON policy example
{
"Id": "Policy1568185116930",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1568184932403",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome",
"Principal": "*"
},
{
"Sid": "Stmt1568185007451",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::welcome/*",
"Principal": "*"
}
]
}

# Update bucket ACL
aws s3api get-bucket-acl --bucket <bucket-name> # Way 1 to get the ACL
aws s3api put-bucket-acl --bucket <bucket-name> --access-control-policy file://acl.json

aws s3api get-object-acl --bucket <bucket-name> --key flag #Way 2 to get the ACL
aws s3api put-object-acl --bucket <bucket-name> --key flag --access-control-policy file://objacl.json

##JSON ACL example
## Make sure to modify the Owner’s displayName and ID according to the Object ACL you retrieved.
{
"Owner": {
"DisplayName": "<DisplayName>",
"ID": "<ID>"
},
"Grants": [
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
},
"Permission": "FULL_CONTROL"
}
]
}
## An ACL should give you the permission WRITE_ACP to be able to put a new ACL
```
### dual-stack <a href="#dual-stack-endpoints-description" id="dual-stack-endpoints-description"></a>

Puoi accedere a un bucket S3 tramite un endpoint dual-stack usando un virtual hosted-style o un path-style endpoint name. Questi sono utili per accedere a S3 tramite IPv6.

Gli endpoint dual-stack usano la seguente sintassi:

- `bucketname.s3.dualstack.aws-region.amazonaws.com`
- `s3.dualstack.aws-region.amazonaws.com/bucketname`

### Privesc

Nella pagina seguente puoi vedere come **abuse S3 permissions to escalate privileges**:

{{#ref}}
../aws-privilege-escalation/aws-s3-privesc/README.md
{{#endref}}

### Unauthenticated Access

{{#ref}}
../aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum/README.md
{{#endref}}

### S3 Post Exploitation

{{#ref}}
../aws-post-exploitation/aws-s3-post-exploitation/README.md
{{#endref}}

### Persistence

{{#ref}}
../aws-persistence/aws-s3-persistence/README.md
{{#endref}}

## Other S3 vulns

### S3 HTTP Cache Poisoning Issue <a href="#heading-s3-http-desync-cache-poisoning-issue" id="heading-s3-http-desync-cache-poisoning-issue"></a>

[**According to this research**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies#heading-s3-http-desync-cache-poisoning-issue) era possibile memorizzare nella cache la risposta di un bucket arbitrario come se appartenesse a uno diverso. Questo poteva essere abusato per modificare, ad esempio, le risposte dei file javascript e compromettere pagine arbitrarie che usano S3 per memorizzare codice statico.

## Amazon Athena

Amazon Athena è un servizio di query interattivo che rende semplice l'**analisi dei dati** direttamente in Amazon Simple Storage Service (Amazon **S3**) **usando** lo standard **SQL**.

Devi preparare una **tabella relazionale DB** con il formato dei contenuti che compariranno nei bucket S3 monitorati. Successivamente, Amazon Athena sarà in grado di popolare la tabella dai log, così potrai interrogarla.

Amazon Athena supporta la **possibilità di interrogare dati S3 già cifrati** e, se configurata per farlo, **Athena può anche cifrare i risultati della query che poi possono essere archiviati in S3**.

**Questa cifratura dei risultati è indipendente dai dati S3 sottostanti interrogati**, il che significa che anche se i dati S3 non sono cifrati, i risultati della query possono esserlo. Un paio di punti da tenere a mente: Amazon Athena supporta solo dati che sono stati **cifrati** con i **seguenti metodi di cifratura S3**, **SSE-S3, SSE-KMS, and CSE-KMS**.

SSE-C e CSE-C non sono supportati. Inoltre, è importante capire che Amazon Athena eseguirà query solo contro **oggetti cifrati che si trovano nella stessa regione della query stessa**. Se hai bisogno di interrogare dati S3 cifrati utilizzando KMS, allora sono necessarie autorizzazioni specifiche per l'utente Athena per consentire l'esecuzione della query.

### Enumerazione
```bash
# Get catalogs
aws athena list-data-catalogs

# Get databases inside catalog
aws athena list-databases --catalog-name <catalog-name>
aws athena list-table-metadata --catalog-name <catalog-name> --database-name <db-name>

# Get query executions, queries and results
aws athena list-query-executions
aws athena get-query-execution --query-execution-id <id> # Get query and meta of results
aws athena get-query-results --query-execution-id <id> # This will rerun the query and get the results

# Get workgroups & Prepared statements
aws athena list-work-groups
aws athena list-prepared-statements --work-group <wg-name>
aws athena get-prepared-statement --statement-name <name> --work-group <wg-name>

# Run query
aws athena start-query-execution --query-string <query>
```
## Riferimenti

- [https://cloudsecdocs.com/aws/defensive/tooling/cli/#s3](https://cloudsecdocs.com/aws/defensive/tooling/cli/#s3)
- [https://docs.aws.amazon.com/AmazonS3/latest/userguide/dual-stack-endpoints.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/dual-stack-endpoints.html)

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