This walkthrough assumes you have CloudGoat setup on your Kali Linux. You can use our post on Working with CloudGoat: The “Vulnerable by Design” AWS Environment as a guide in deploying it.
Scenario summary
The scenario starts with an IAM user Solus. The attacker discovers they have ReadOnly permissions to a Lambda function, where hardcoded secrets lead them to an EC2 instance running a web application that is vulnerable to SSRF. After exploiting the vulnerable app and acquiring keys from the EC2 metadata service, the attacker gains access to a private S3 bucket with a set of keys that allow them to invoke the Lambda function and complete the scenario. Goal: Invoke the Lambda function. Walkthrough To deploy the resources for each scenario on AWS. ./cloudgoat.py create ec2_ssrf
Deploying the resources gives us the access key and secret key for Solus.
Save the credential to a profile – Solus.
aws configure –profile Solus
Perform reconnaissance on the user “Solus” to see what privileges the user has by enumerating the policies and permissions attached to the user.
We tried running the usual commands, such as “list-user-policies”, “list-attached-user-policies” and “list roles”, and we noticed we were not authorized to carry out those actions.
aws iam list-user-policies –-user-name
Since we are unable to get more information about Solus, we perform a recon on the Lambda function.
aws lambda list-functions –region us-east-1 –profile
list-function: Returns a list of Lambda functions, with the version-specific configuration of each. Lambda returns up to 50 functions per call.
We notice that the Lambda function has an access key and a secret key stored in the environment variables. We want to find out more information about this Lambda function.
aws lambda get-function –function-name
Save the compromised credential from the Lambda function in another profile – Lambda_Solus.
aws configure –profile Lambda_Solus
Perform a recon on the compromised credential.
We can assume it was assigned to a user “Wrex”. We tried running the usual commands: “list-user-policies”, “list-attached-user-policies” and “list-roles”. We were not authorized to carry out those actions.
Get more information about the EC2 instance running.
aws ec2 describe-instances –region us-east-1 –profile
describe-instances: Describes the specified instances or all instances.
Let’s visit the public IP address of the EC2 Instance, since it has port 80 enabled.
We immediately notice an error. Since we already know the scenario has to do with SSRF, we manipulate the server to make HTTP requests to an arbitrary domain (in our case, the localhost). SSRF is a vulnerability that tricks the web applications into making HTTP requests on behalf of the bad actor to a URL. This allows the bad actor to gain access to sensitive information or data that are directly exposed or the bad actor does not have access to such as the AWS metadata, other web applications based within the organization’s infrastructure or external web services. In some cases, the bad actor is also able to perform arbitrary command execution. We exploit this vulnerability by querying the instance metadata API to obtain the credentials to reveal the role name of the EC2 instance. The instance metadata contains data about the EC2 instance that you can use to configure or manage the running instance.
This returns the access key ID, secret access key and the session token of the IAM role attached to the EC2 instance. This credential is a temporary one, as it has an expiration date.
Save the compromised credential from the instance metadata in another profile — ec2role. We do a bit of recon using our newly compromised credential. We use this credential to gather information about the S3 buckets.
aws s3 ls –profile
Accessing the S3 bucket reveals that it has an admin file stored with an access key and secret key ID.
Save the compromised credential in another profile — AdminUser.
aws configure –profile AdminUser
Perform a recon on the compromised credential.
We can assume it was assigned to a user named “Shepard”.
We tried running the usual commands — “list-attached-user-policies”, “list-user-policies” and “list-roles” — to gain more information about the permissions assigned to the user.
aws iam list-attached-user-policies –-user-name
list-attached-user-policies: Lists all managed policies that are attached to the specified IAM user.
aws iam get-policy –policy-arn
aws iam get-policy-version –policy-arn
We have full admin privileges with this credential.
We invoke the function and see what happens.
aws lambda invoke –function-name
To destroy the resources created during this lab:
./cloudgoat.py destroy ec2_ssrf
Summary
In this scenario, we were able to exploit a number of misconfigurations and bad practices to gain access to the sensitive data.
Credentials (access key and a secret key) were stored in the environment variables of a Lambda function. Due to the SSRF vulnerability on the web application, we were able to gain access to yet another set of credentials via the AWS metadata API. Admin credentials were also stored in an S3 bucket, which eventually gave us full privileges.
Sources
AWS CLI Command Reference – IAM, AWS Well, that escalated quickly, Bishop Fox AWS IAM Privilege Escalation Methods, Rhino Security Labs Server Side Request Forgery, OWASP Server-side request forgery (SSRF), PortSwigger