# AWS - DynamoDB Enum

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

## DynamoDB

### Informations de base

Amazon DynamoDB est présenté par AWS comme une **base de données NoSQL clé-valeur, entièrement gérée et sans serveur**, conçue pour alimenter des applications haute performance, quelle que soit leur taille. Le service garantit des fonctionnalités robustes, y compris des mesures de sécurité inhérentes, des sauvegardes ininterrompues, une réplication automatisée à travers plusieurs régions, un cache en mémoire intégré et des utilitaires d'exportation de données pratiques.

Dans le contexte de DynamoDB, au lieu d'établir une base de données traditionnelle, **des tables sont créées**. Chaque table nécessite la spécification d'une **clé de partition** comme composant intégral de **la clé primaire de la table**. Cette clé de partition, essentiellement une **valeur de hachage**, joue un rôle critique tant dans la récupération des éléments que dans la distribution des données à travers divers hôtes. Cette distribution est essentielle pour maintenir à la fois la scalabilité et la disponibilité de la base de données. De plus, il est possible d'incorporer une **clé de tri** pour affiner davantage l'organisation des données.

### Chiffrement

Par défaut, DynamoDB utilise une clé KMS qui **appartient à Amazon DynamoDB,** pas même la clé gérée par AWS qui appartient au moins à votre compte.

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

### Sauvegardes et exportation vers S3

Il est possible de **programmer** la génération de **sauvegardes de table** ou de les créer à la **demande**. De plus, il est également possible d'activer **la récupération à un instant donné (PITR) pour une table.** La récupération à un instant donné fournit des **sauvegardes** continues de vos données DynamoDB pendant **35 jours** pour vous aider à vous protéger contre des opérations d'écriture ou de suppression accidentelles.

Il est également possible d'exporter **les données d'une table vers S3**, mais la table doit avoir **PITR activé**.

### GUI

Il existe une interface graphique pour les services Dynamo locaux comme [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), etc., qui pourrait être utile : [https://github.com/aaronshaf/dynamodb-admin](https://github.com/aaronshaf/dynamodb-admin)

### Énumération
```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
```
### Accès non authentifié

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

### Privesc

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

### Post Exploitation

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

### Persistance

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

## Injection DynamoDB

### Injection SQL

Il existe des moyens d'accéder aux données DynamoDB avec **la syntaxe SQL**, donc, des **injections SQL typiques sont également possibles**.

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

### Injection NoSQL

Dans DynamoDB, différentes **conditions** peuvent être utilisées pour récupérer des données, comme dans une injection NoSQL classique. S'il est possible de **chaîner plus de conditions pour récupérer** des données, vous pourriez obtenir des données cachées (ou vider toute la table).\
Vous pouvez trouver ici les conditions prises en charge par DynamoDB : [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html)

Notez que **différentes conditions** sont prises en charge si les données sont accessibles via **`query`** ou via **`scan`**.

> [!NOTE]
> En fait, les actions **Query** doivent spécifier la **condition "EQ" (égal)** dans la **clé primaire** pour fonctionner, ce qui les rend beaucoup **moins sujettes aux injections NoSQL** (et rend également l'opération très limitée).

Si vous pouvez **modifier la comparaison** effectuée ou en ajouter de nouvelles, vous pourriez récupérer plus de données.
```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}}

### Injection Json brute

> [!CAUTION]
> **Cette vulnérabilité est basée sur le filtre de scan de dynamodb qui est maintenant obsolète !**

**DynamoDB** accepte des objets **Json** pour **rechercher** des données dans la DB. Si vous constatez que vous pouvez écrire dans l'objet json envoyé pour la recherche, vous pourriez faire un dump de la DB, tout le contenu.

Par exemple, injecter dans une requête comme :
```bash
'{"Id": {"ComparisonOperator": "EQ","AttributeValueList": [{"N": "' + user_input + '"}]}}'
```
un attaquant pourrait injecter quelque chose comme :

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

corriger la condition "EQ" en recherchant l'ID 1000 et ensuite en cherchant toutes les données avec une chaîne d'Id supérieure à 0, ce qui est tout.

Un autre **exemple vulnérable utilisant une connexion** pourrait être :
```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))
```
Cela serait vulnérable à :
```
username: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
password: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
```
### :property Injection

Certain SDKs permettent d'utiliser une chaîne indiquant le filtrage à effectuer comme :
```java
new ScanSpec().withProjectionExpression("UserName").withFilterExpression(user_input+" = :username and Password = :password").withValueMap(valueMap)
```
Vous devez savoir que la recherche dans DynamoDB pour **substituer** une **valeur** d'attribut dans des **expressions de filtre** lors de la numérisation des éléments, les tokens doivent **commencer** par le caractère **`:`**. Ces tokens seront **remplacés** par la véritable **valeur d'attribut à l'exécution**.

Par conséquent, une connexion comme la précédente peut être contournée avec quelque chose comme :
```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}}
