Privilege Escalation in EC2, using Session Manager

The dangers of granting ssm:StartSession permissions to your EC2 instances
3 min read

Background

AWS’s SSM Session Manager service is pretty nice. It allows for shell access to EC2 instances without needing to open up SSH ports to the world or configure security groups. All sessions are logged to Session Manager and you can restrict access to authorized groups of IAM users using policies.

Your EC2 instances may end up needing some ssm: permissions, for example, the ones built into AmazonSSMManagedInstanceCore for communication with Fleet Manager, etc.

One might be tempted to allow all SSM commands via ssm:*. This is a pretty bad idea.

The Problem

There are two problems here. First, we know already that Session Manager can both open shells into other instances, but has the additional feature of letting you choose the user that you connect as. Thankfully, root is not allowed, but you can use this use this to access other user accounts on an EC2 instance.

Theoretically, you could use this to drop a backdoor in a web server by using access as apache or nginx.

If the instance also has EC2 permissions to list instances AND the ssm:StartSession permission for them, it effectively grants an attacker the ability to log into any instance on your network.

Exploiting This

During one of the lab exercises for my Cybersecurity Master’s program, we were tasked with trying to elevate our privileges on a locked-down user on an EC2 instance. These instances (deployed via AWS’s Educate tool) had a custom policy enabled which allowed the instance to perform the ssm:StartSession API call using the instance’s role.

Since I wasn’t able to install things, I hacked together a pure-Python implementation of the AWS session manager command line, which allowed me to log into another, more privileged user (for example, apache).

This requires minimal packages (just python) and does not need root privileges to download and run as long as python and pip are installed. Since Python is pretty much universally available, and boto3 is commonly installed, this worked pretty well.

I used this to drop a suid/sgid binary as a backdoor to regain access as the target user without needing session manager. From there, my locked down user could execute the binary and get immediate access to things such as web server configuration, or other administrator accounts on the system.

Conclusion

Don’t give your EC2 instances more permissions than they need.

Avoid giving EC2 instances permissions such as ssm:StartSession or ssm:RunCommand. In a lot of cases, this is not necessary and opens up the possibility of an attacker moving laterally across your network, planting backdoors, etc.

Subscribe to my Newsletter

Like this post? Subscribe to get notified for future posts like this.

Change Log

  • 8/30/2024 - Initial Revision

Found a typo or technical problem? file an issue!