orenma

aws-perm-check.sh

Aug 14th, 2025 (edited)
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 19.77 KB | Cybersecurity | 0 0
  1. #!/bin/bash
  2.  
  3. # =============================================================================
  4. # Modular AWS Permission Checker
  5. # Description: Check specific AWS permissions for current session
  6. # Usage: ./aws-perm-check.sh [module] [options]
  7. # =============================================================================
  8.  
  9.  
  10. # Global variables
  11. SCRIPT_NAME="$(basename "$0")"
  12. QUIET_MODE=false
  13. VERBOSE_MODE=false
  14. OUTPUT_FORMAT="text"  # text, json, csv
  15.  
  16. # Color codes for output
  17. RED='\033[0;31m'
  18. GREEN='\033[0;32m'
  19. YELLOW='\033[1;33m'
  20. BLUE='\033[0;34m'
  21. NC='\033[0m' # No Color
  22.  
  23. # =============================================================================
  24. # Core Functions
  25. # =============================================================================
  26.  
  27. log_info() {
  28.     [[ "$QUIET_MODE" == true ]] && return
  29.     echo -e "${BLUE}[INFO]${NC} $1"
  30. }
  31.  
  32. log_success() {
  33.     [[ "$QUIET_MODE" == true ]] && return
  34.     echo -e "${GREEN}[SUCCESS]${NC} $1"
  35. }
  36.  
  37. log_warning() {
  38.     echo -e "${YELLOW}[WARNING]${NC} $1" >&2
  39. }
  40.  
  41. log_error() {
  42.     echo -e "${RED}[ERROR]${NC} $1" >&2
  43. }
  44.  
  45. show_usage() {
  46.     cat << EOF
  47. Usage: $SCRIPT_NAME [MODULE] [OPTIONS]
  48.  
  49. MODULES:
  50.     core        - Basic AWS identity and core permissions
  51.     ec2         - EC2 service permissions
  52.     s3          - S3 service permissions
  53.     iam         - IAM service permissions
  54.     ssm         - Systems Manager permissions
  55.     rds         - RDS service permissions
  56.     ecr         - Elastic Container Registry permissions
  57.     cloudwatch  - CloudWatch permissions
  58.     jenkins     - Jenkins-specific privilege escalation checks
  59.     all         - Run all modules
  60.  
  61. OPTIONS:
  62.     -q, --quiet     Quiet mode (minimal output)
  63.     -v, --verbose   Verbose mode (detailed output)
  64.     -f, --format    Output format: text|json|csv (default: text)
  65.     -h, --help      Show this help message
  66.  
  67. EXAMPLES:
  68.     $SCRIPT_NAME core                    # Check core permissions
  69.     $SCRIPT_NAME ec2 -v                  # Check EC2 with verbose output
  70.     $SCRIPT_NAME all -f json             # All checks in JSON format
  71.     $SCRIPT_NAME iam --quiet             # IAM checks with minimal output
  72.  
  73. EOF
  74. }
  75.  
  76. # Verify AWS credentials
  77. verify_aws_credentials() {
  78.     log_info "Verifying AWS credentials..."
  79.    
  80.     if ! aws sts get-caller-identity &>/dev/null; then
  81.         log_error "AWS credentials not configured or invalid"
  82.         log_error "Please ensure you have configured:"
  83.         log_error "  - AWS Access Key ID"
  84.         log_error "  - AWS Secret Access Key"
  85.         log_error "  - AWS Session Token (if using temporary credentials)"
  86.         exit 1
  87.     fi
  88.    
  89.     log_success "AWS credentials verified"
  90. }
  91.  
  92. # Get caller identity information
  93. get_caller_info() {
  94.     local caller_arn=$(aws sts get-caller-identity --query 'Arn' --output text)
  95.     local caller_type=$(echo "$caller_arn" | cut -d':' -f6 | cut -d'/' -f1)
  96.     local caller_name=$(echo "$caller_arn" | cut -d'/' -f2)
  97.     local account_id=$(aws sts get-caller-identity --query 'Account' --output text)
  98.    
  99.     echo "$caller_type|$caller_name|$account_id|$caller_arn"
  100. }
  101.  
  102. # Test a specific permission
  103. test_permission() {
  104.     local service="$1"
  105.     local action="$2"
  106.     local test_command="$3"
  107.     local description="${4:-}"
  108.    
  109.     local full_action="${service}:${action}"
  110.     [[ -n "$description" ]] && full_action="$full_action ($description)"
  111.    
  112.     if [[ "$VERBOSE_MODE" == true ]]; then
  113.         log_info "Testing $full_action..."
  114.         log_info "Command: $test_command"
  115.     elif [[ "$QUIET_MODE" == false ]]; then
  116.         echo -n "Testing $full_action... "
  117.     fi
  118.    
  119.     if eval "$test_command &>/dev/null"; then
  120.         [[ "$QUIET_MODE" == false ]] && echo -e "${GREEN}✅ Allowed${NC}"
  121.         [[ "$VERBOSE_MODE" == true ]] && log_success "Permission allowed"
  122.         return 0
  123.     else
  124.         [[ "$QUIET_MODE" == false ]] && echo -e "${RED}❌ Denied${NC}"
  125.         [[ "$VERBOSE_MODE" == true ]] && log_warning "Permission denied"
  126.         return 1
  127.     fi
  128. }
  129.  
  130. # =============================================================================
  131. # Module Functions
  132. # =============================================================================
  133.  
  134. module_core() {
  135.     log_info "Running core permissions check..."
  136.    
  137.     local caller_info=$(get_caller_info)
  138.     local caller_type=$(echo "$caller_info" | cut -d'|' -f1)
  139.     local caller_name=$(echo "$caller_info" | cut -d'|' -f2)
  140.     local account_id=$(echo "$caller_info" | cut -d'|' -f3)
  141.     local caller_arn=$(echo "$caller_info" | cut -d'|' -f4)
  142.    
  143.     echo "=== AWS Identity Information ==="
  144.     echo "Identity Type: $caller_type"
  145.     echo "Identity Name: $caller_name"
  146.     echo "Account ID: $account_id"
  147.     echo "Full ARN: $caller_arn"
  148.     echo
  149.    
  150.     echo "=== Core Permissions ==="
  151.     test_permission "STS" "GetCallerIdentity" "aws sts get-caller-identity" "Current identity"
  152. }
  153.  
  154. module_ec2() {
  155.     log_info "Running EC2 permissions check..."
  156.    
  157.     echo "=== EC2 Permissions ==="
  158.     test_permission "EC2" "DescribeInstances" "aws ec2 describe-instances --max-items 1"
  159.     test_permission "EC2" "DescribeSecurityGroups" "aws ec2 describe-security-groups --max-items 1"
  160.     test_permission "EC2" "DescribeVpcs" "aws ec2 describe-vpcs --max-items 1"
  161.     test_permission "EC2" "DescribeInstanceTypes" "aws ec2 describe-instance-types --max-items 1"
  162.     test_permission "EC2" "DescribeImages" "aws ec2 describe-images --owners self --max-items 1"
  163.     test_permission "EC2" "DescribeKeyPairs" "aws ec2 describe-key-pairs --max-items 1"
  164. }
  165.  
  166. module_s3() {
  167.     log_info "Running S3 permissions check..."
  168.    
  169.     echo "=== S3 Permissions ==="
  170.     test_permission "S3" "ListAllMyBuckets" "aws s3 ls"
  171.    
  172.     # Test S3 GetObject only if ListBuckets succeeded
  173.     if aws s3 ls &>/dev/null; then
  174.         local first_bucket=$(aws s3 ls | head -n 1 | awk '{print $3}' 2>/dev/null)
  175.         if [[ -n "$first_bucket" ]]; then
  176.             test_permission "S3" "ListBucket" "aws s3api list-objects --bucket $first_bucket --max-items 1" "List objects in $first_bucket"
  177.             test_permission "S3" "GetBucketLocation" "aws s3api get-bucket-location --bucket $first_bucket" "Get $first_bucket location"
  178.         else
  179.             log_warning "No S3 buckets found to test object-level permissions"
  180.         fi
  181.     fi
  182. }
  183.  
  184. module_iam() {
  185.     log_info "Running IAM permissions check..."
  186.    
  187.     echo "=== IAM Permissions ==="
  188.     test_permission "IAM" "ListRoles" "aws iam list-roles --max-items 1"
  189.     test_permission "IAM" "ListPolicies" "aws iam list-policies --max-items 1"
  190.     test_permission "IAM" "ListUsers" "aws iam list-users --max-items 1"
  191.     test_permission "IAM" "GetAccountSummary" "aws iam get-account-summary"
  192.     test_permission "IAM" "ListAccountAliases" "aws iam list-account-aliases"
  193.    
  194.     # Get current identity policies if possible
  195.     local caller_info=$(get_caller_info)
  196.     local caller_type=$(echo "$caller_info" | cut -d'|' -f1)
  197.     local caller_name=$(echo "$caller_info" | cut -d'|' -f2)
  198.    
  199.     echo
  200.     echo "=== Current Identity Policy Information ==="
  201.     if [[ "$caller_type" == "role" || "$caller_type" == "assumed-role" ]]; then
  202.         test_permission "IAM" "ListAttachedRolePolicies" "aws iam list-attached-role-policies --role-name $caller_name" "List policies for current role"
  203.         test_permission "IAM" "ListRolePolicies" "aws iam list-role-policies --role-name $caller_name" "List inline policies for current role"
  204.     elif [[ "$caller_type" == "user" ]]; then
  205.         test_permission "IAM" "ListAttachedUserPolicies" "aws iam list-attached-user-policies --user-name $caller_name" "List policies for current user"
  206.         test_permission "IAM" "ListUserPolicies" "aws iam list-user-policies --user-name $caller_name" "List inline policies for current user"
  207.     fi
  208. }
  209.  
  210. module_ssm() {
  211.     log_info "Running SSM permissions check..."
  212.    
  213.     echo "=== Systems Manager Permissions ==="
  214.     test_permission "SSM" "DescribeInstanceInformation" "aws ssm describe-instance-information --max-items 1"
  215.     test_permission "SSM" "ListCommands" "aws ssm list-commands --max-items 1"
  216.     test_permission "SSM" "DescribeParameters" "aws ssm describe-parameters --max-items 1"
  217.     test_permission "SSM" "GetParameters" "aws ssm get-parameters --names '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' || true"
  218. }
  219.  
  220. module_rds() {
  221.     log_info "Running RDS permissions check..."
  222.    
  223.     echo "=== RDS Permissions ==="
  224.     test_permission "RDS" "DescribeDBInstances" "aws rds describe-db-instances --max-items 1"
  225.     test_permission "RDS" "DescribeDBClusters" "aws rds describe-db-clusters --max-items 1"
  226.     test_permission "RDS" "DescribeDBSubnetGroups" "aws rds describe-db-subnet-groups --max-items 1"
  227. }
  228.  
  229. module_ecr() {
  230.     log_info "Running ECR permissions check..."
  231.    
  232.     echo "=== ECR Permissions ==="
  233.     test_permission "ECR" "DescribeRepositories" "aws ecr describe-repositories --max-items 1"
  234.     test_permission "ECR" "GetAuthorizationToken" "aws ecr get-authorization-token"
  235. }
  236.  
  237. module_cloudwatch() {
  238.     log_info "Running CloudWatch permissions check..."
  239.    
  240.     echo "=== CloudWatch Permissions ==="
  241.     test_permission "CloudWatch" "ListMetrics" "aws cloudwatch list-metrics --max-items 1"
  242.     test_permission "CloudWatch" "DescribeAlarms" "aws cloudwatch describe-alarms --max-items 1"
  243.     test_permission "Logs" "DescribeLogGroups" "aws logs describe-log-groups --max-items 1"
  244. }
  245.  
  246. module_jenkins() {
  247.     log_info "Running Jenkins privilege escalation check..."
  248.    
  249.     # Get current caller information
  250.     local caller_info=$(get_caller_info)
  251.     local caller_type=$(echo "$caller_info" | cut -d'|' -f1)
  252.     local caller_name=$(echo "$caller_info" | cut -d'|' -f2)
  253.     local caller_arn=$(echo "$caller_info" | cut -d'|' -f4)
  254.    
  255.     # Check if current session is using a role (required for Jenkins escalation)
  256.     if [[ "$caller_type" != "role" && "$caller_type" != "assumed-role" ]]; then
  257.         log_warning "Current session is not using a role (type: $caller_type)"
  258.         log_warning "Jenkins privilege escalation typically requires role-based access"
  259.         echo "Current identity: $caller_arn"
  260.         return 1
  261.     fi
  262.    
  263.     # Extract the role name from current session
  264.     local current_role="$caller_name"
  265.     local admin_policy_arn="arn:aws:iam::aws:policy/AdministratorAccess"
  266.    
  267.     echo "=== Jenkins Privilege Escalation Permissions ==="
  268.     echo "Current Role: $current_role"
  269.     echo "Full ARN: $caller_arn"
  270.     echo
  271.    
  272.     # Check if this looks like a Jenkins role
  273.     if [[ "$current_role" =~ jenkins|Jenkins ]]; then
  274.         log_info "Detected Jenkins-related role name"
  275.     else
  276.         log_warning "Current role doesn't appear to be Jenkins-related"
  277.         log_info "Proceeding with privilege escalation checks anyway..."
  278.     fi
  279.    
  280.     echo
  281.     echo "=== Current Role Analysis ==="
  282.     test_permission "IAM" "GetRole" "aws iam get-role --role-name $current_role" "Get current role details"
  283.     test_permission "IAM" "ListAttachedRolePolicies" "aws iam list-attached-role-policies --role-name $current_role" "List current role policies"
  284.     test_permission "IAM" "ListRolePolicies" "aws iam list-role-policies --role-name $current_role" "List inline policies for current role"
  285.    
  286.     # Test privilege escalation capabilities
  287.     echo
  288.     echo "=== Privilege Escalation Tests ==="
  289.    
  290.     local can_attach=false
  291.     local can_put_policy=false
  292.     local can_create_role=false
  293.    
  294.     # Test AttachRolePolicy permission (most critical)
  295.     echo "Testing IAM:AttachRolePolicy... "
  296.     if aws iam attach-role-policy --role-name "$current_role" --policy-arn "$admin_policy_arn" &>/dev/null; then
  297.         echo -e "${GREEN}✅ Allowed - CRITICAL VULNERABILITY!${NC}"
  298.         can_attach=true
  299.         # Immediately detach to clean up
  300.         aws iam detach-role-policy --role-name "$current_role" --policy-arn "$admin_policy_arn" &>/dev/null
  301.         echo "  → Automatically detached policy for safety"
  302.     else
  303.         echo -e "${RED}❌ Denied${NC}"
  304.     fi
  305.    
  306.     # Test DetachRolePolicy permission
  307.     test_permission "IAM" "DetachRolePolicy" "aws iam detach-role-policy --role-name $current_role --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess --dry-run" "Detach policies from current role"
  308.    
  309.     # Test PutRolePolicy permission (inline policy creation)
  310.     echo "Testing IAM:PutRolePolicy... "
  311.     if aws iam put-role-policy --role-name "$current_role" --policy-name "test-escalation-policy" --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' &>/dev/null; then
  312.         echo -e "${GREEN}✅ Allowed - CRITICAL VULNERABILITY!${NC}"
  313.         can_put_policy=true
  314.         # Immediately delete the policy
  315.         aws iam delete-role-policy --role-name "$current_role" --policy-name "test-escalation-policy" &>/dev/null
  316.         echo "  → Automatically deleted test policy for safety"
  317.     else
  318.         echo -e "${RED}❌ Denied${NC}"
  319.     fi
  320.    
  321.     # Test CreateRole permission
  322.     echo "Testing IAM:CreateRole... "
  323.     if aws iam create-role --role-name "test-escalation-role-$" --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}' &>/dev/null; then
  324.         echo -e "${YELLOW}✅ Allowed - Potential escalation path${NC}"
  325.         can_create_role=true
  326.         # Clean up the test role
  327.         aws iam delete-role --role-name "test-escalation-role-$" &>/dev/null
  328.         echo "  → Automatically deleted test role for safety"
  329.     else
  330.         echo -e "${RED}❌ Denied${NC}"
  331.     fi
  332.    
  333.     # Additional privilege escalation tests
  334.     test_permission "IAM" "UpdateAssumeRolePolicy" "aws iam update-assume-role-policy --role-name $current_role --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}' --dry-run" "Modify role trust policy"
  335.    
  336.     test_permission "IAM" "CreatePolicy" "aws iam create-policy --policy-name test-policy-$ --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"s3:ListBucket\",\"Resource\":\"*\"}]}' --dry-run" "Create new policies"
  337.    
  338.     test_permission "IAM" "PassRole" "aws iam get-role --role-name $current_role" "Pass role to services"
  339.    
  340.     # Test if we can modify other Jenkins roles (if any exist)
  341.     echo
  342.     echo "=== Other Jenkins Roles Check ==="
  343.     log_info "Searching for other Jenkins-related roles..."
  344.    
  345.     if aws iam list-roles --query 'Roles[?contains(RoleName, `jenkins`) || contains(RoleName, `Jenkins`)].RoleName' --output text 2>/dev/null | grep -v "^$" | while read -r jenkins_role; do
  346.         if [[ "$jenkins_role" != "$current_role" && -n "$jenkins_role" ]]; then
  347.             echo "Found Jenkins role: $jenkins_role"
  348.             test_permission "IAM" "AttachRolePolicy" "aws iam attach-role-policy --role-name $jenkins_role --policy-arn $admin_policy_arn --dry-run 2>/dev/null" "Attach policy to $jenkins_role"
  349.         fi
  350.     done; then
  351.         log_info "Completed search for other Jenkins roles"
  352.     else
  353.         log_warning "Could not search for other Jenkins roles (insufficient ListRoles permission)"
  354.     fi
  355.    
  356.     echo
  357.     echo "=== Privilege Escalation Summary ==="
  358.     if [[ "$can_attach" == true ]]; then
  359.         log_warning "🚨 CRITICAL PRIVILEGE ESCALATION POSSIBLE! 🚨"
  360.         echo
  361.         echo "Critical findings:"
  362.         echo "- Can attach AdministratorAccess policy to current role"
  363.         echo "- Current role: $current_role"
  364.         echo
  365.         echo "Escalation commands:"
  366.         echo "1. aws iam attach-role-policy --role-name '$current_role' --policy-arn '$admin_policy_arn'"
  367.         echo "2. aws sts get-caller-identity  # Verify new permissions"
  368.         echo "3. # You now have full AWS admin access!"
  369.         echo
  370.         echo "Cleanup command (to remove escalation):"
  371.         echo "aws iam detach-role-policy --role-name '$current_role' --policy-arn '$admin_policy_arn'"
  372.     elif [[ "$can_put_policy" == true ]]; then
  373.         log_warning "🚨 PRIVILEGE ESCALATION POSSIBLE VIA INLINE POLICY! 🚨"
  374.         echo
  375.         echo "Critical findings:"
  376.         echo "- Can create admin inline policies on current role"
  377.         echo "- Current role: $current_role"
  378.         echo
  379.         echo "Escalation commands:"
  380.         echo "1. aws iam put-role-policy --role-name '$current_role' --policy-name admin-policy --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}]}'"
  381.         echo "2. aws sts get-caller-identity  # Verify new permissions"
  382.         echo "3. # You now have full AWS admin access!"
  383.         echo
  384.         echo "Cleanup command (to remove escalation):"
  385.         echo "aws iam delete-role-policy --role-name '$current_role' --policy-name admin-policy"
  386.     elif [[ "$can_create_role" == true ]]; then
  387.         log_warning "⚠️  POTENTIAL PRIVILEGE ESCALATION VIA ROLE CREATION"
  388.         echo
  389.         echo "Findings:"
  390.         echo "- Can create new roles (requires additional permissions to escalate)"
  391.         echo "- Need iam:AttachRolePolicy or iam:PutRolePolicy on new roles to escalate"
  392.         echo "- May be able to create roles with broader permissions"
  393.     else
  394.         log_info "✅ Direct privilege escalation not detected"
  395.         echo "Current role appears to have limited IAM permissions"
  396.         echo "Note: This doesn't guarantee safety - other escalation paths may exist"
  397.     fi
  398. }
  399.  
  400. # =============================================================================
  401. # Main Script Logic
  402. # =============================================================================
  403.  
  404. main() {
  405.     local module=""
  406.    
  407.     # Parse command line arguments
  408.     while [[ $# -gt 0 ]]; do
  409.         case $1 in
  410.             -h|--help)
  411.                 show_usage
  412.                 exit 0
  413.                 ;;
  414.             -q|--quiet)
  415.                 QUIET_MODE=true
  416.                 shift
  417.                 ;;
  418.             -v|--verbose)
  419.                 VERBOSE_MODE=true
  420.                 shift
  421.                 ;;
  422.             -f|--format)
  423.                 OUTPUT_FORMAT="$2"
  424.                 shift 2
  425.                 ;;
  426.             core|ec2|s3|iam|ssm|rds|ecr|cloudwatch|jenkins|all)
  427.                 module="$1"
  428.                 shift
  429.                 ;;
  430.             *)
  431.                 log_error "Unknown option: $1"
  432.                 show_usage
  433.                 exit 1
  434.                 ;;
  435.         esac
  436.     done
  437.    
  438.     # If no module specified, show usage
  439.     if [[ -z "$module" ]]; then
  440.         show_usage
  441.         exit 1
  442.     fi
  443.    
  444.     # Verify AWS credentials
  445.     verify_aws_credentials
  446.     echo
  447.    
  448.     # Run the specified module(s)
  449.     case $module in
  450.         core)
  451.             module_core
  452.             ;;
  453.         ec2)
  454.             module_ec2
  455.             ;;
  456.         s3)
  457.             module_s3
  458.             ;;
  459.         iam)
  460.             module_iam
  461.             ;;
  462.         ssm)
  463.             module_ssm
  464.             ;;
  465.         rds)
  466.             module_rds
  467.             ;;
  468.         ecr)
  469.             module_ecr
  470.             ;;
  471.         cloudwatch)
  472.             module_cloudwatch
  473.             ;;
  474.         jenkins)
  475.             module_jenkins
  476.             ;;
  477.         all)
  478.             module_core
  479.             echo
  480.             module_ec2
  481.             echo
  482.             module_s3
  483.             echo
  484.             module_iam
  485.             echo
  486.             module_ssm
  487.             echo
  488.             module_rds
  489.             echo
  490.             module_ecr
  491.             echo
  492.             module_cloudwatch
  493.             echo
  494.             module_jenkins
  495.             ;;
  496.     esac
  497.    
  498.     echo
  499.     log_info "Permission check complete for module: $module"
  500. }
  501.  
  502. # Run main function with all arguments
  503. main "$@"
Advertisement
Add Comment
Please, Sign In to add comment