diff --git a/util/org-multi-account/ProwlerEC2.yaml b/util/org-multi-account/ProwlerEC2.yaml new file mode 100644 index 00000000..c33f9895 --- /dev/null +++ b/util/org-multi-account/ProwlerEC2.yaml @@ -0,0 +1,449 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create Prowler EC2 with UserData (Shell Scripts, & AWS CLI Profiles) + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: EC2 Instance Settings + Parameters: + - BuildNumber + - Ec2Name + - InstanceType + - KeyPair + - SubnetId + - VpcId + - Ec2Role + - LatestAmazonLinux2AmiId + - ProwlerCron + - Label: + default: S3 Settings + Parameters: + - S3 + - S3Account + - Label: + default: CrossAccount Role + Parameters: + - AwsOrgId + - CrossAccountRole + +Parameters: + BuildNumber: + Type: String + Description: Enter Build Number (increment with Updates for cfn-init) + AllowedPattern: ^\d*$ + ConstraintDescription: Build Number must be a numeric string. + Default: 1 + Ec2Name: + Type: String + Description: Enter Name for EC2 Instance to create + Default: Prowler-EC2 + InstanceType: + Description: Enter Instance Type + Type: String + Default: t2.micro + KeyPair: + Description: Choose a KeyPair + Type: AWS::EC2::KeyPair::KeyName + Default: delgjul-labctaudit + SubnetId: + Description: Choose Subnet + Type: AWS::EC2::Subnet::Id + Default: subnet-04dfbeda2dc588875 + VpcId: + Description: Choose VPC + Type: AWS::EC2::VPC::Id + Default: vpc-0285f35dd91ac4c58 + Ec2Role: + Description: Enter Name for EC2 Instance Role to create + Type: String + Default: ProwlerEC2-Role + ProwlerCron: + Description: Enter cron schedule. Default, runs everyday at 1am. See https://crontab.guru/, for syntax help. + Type: String + Default: 10 * * * * + LatestAmazonLinux2AmiId: + Type: AWS::SSM::Parameter::Value + Description: Latest AMI ID for Amazon Linux 2 (via AWS Publis SSM Parameters. See https://tinyurl.com/aws-public-ssm-parameters. + Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs + + S3: + Type: String + Description: Enter S3 Bucket to grant rights to EC2 Instance + Default: prowler-417425889548-us-east-1 + S3Account: + Type: String + Description: Enter AWS Account Number where S3 Bucket resides + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 417425889548 + + AwsOrgId: + Type: String + Description: Enter AWS Organizations ID + AllowedPattern: ^o-[a-z0-9]{10,32}$ + ConstraintDescription: The Org Id must be a 12 character string starting with o- and followed by 10 lower case alphanumeric characters. + Default: o-nbfb46ay7u + CrossAccountRole: + Type: String + Description: Enter CrossAccount Role you will be using across the AWS Organization + Default: ProwlerXA-Role + +Resources: + ProwlerEc2: + Type: AWS::EC2::Instance + CreationPolicy: + ResourceSignal: + Timeout: PT5M + Properties: + KeyName: !Ref KeyPair + ImageId: !Ref LatestAmazonLinux2AmiId + IamInstanceProfile: !Ref ProwlerInstanceProfile + InstanceType: !Ref InstanceType + SubnetId: !Ref SubnetId + SecurityGroupIds: + - !Ref ProwlerSecurityGroup + Tags: + - Key: Name + Value: !Ref Ec2Name + UserData: + Fn::Base64: + !Sub | + #!/bin/bash + yum update -y aws-cfn-bootstrap + /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ProwlerEc2 --configsets onfirstboot --region ${AWS::Region} + yum -y update + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ProwlerEc2 --region ${AWS::Region} + Metadata: + AWS::CloudFormation::Authentication: + S3AccessCreds: + type: S3 + buckets: + - !Ref S3 + roleName: + Ref: ProwlerEc2Role + AWS::CloudFormation::Init: + configSets: + onfirstboot: + - build-number + - configure-cfn + - prowler-prereqs + - prowler-reports + - prowler-schedule + onupdate: + - build-number + - prowler-prereqs + - prowler-reports + - prowler-schedule + build-number: + commands: + show-build-number: + command: !Sub | + echo "BUILDNUMBER: ${BuildNumber}" + configure-cfn: + files: + /etc/cfn/hooks.d/cfn-auto-reloader.conf: + content: !Sub | + [cfn-auto-reloader-hook] + triggers=post.update + path=Resources.ProwlerEc2.Metadata.AWS::CloudFormation::Init + action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ProwlerEc2 --configsets onupdate --region ${AWS::Region} + runas=root + mode: "000400" + owner: root + group: root + /etc/cfn/cfn-hup.conf: + content: !Sub | + [main] + stack=${AWS::StackId} + region=${AWS::Region} + verbose=true + interval=5 + mode: "000400" + owner: root + group: root + services: + sysvinit: + cfn-hup: + enabled: true + ensureRunning: true + files: + - /etc/cfn/cfn-hup.conf + - /etc/cfn/hooks.d/cfn-auto-reloader.conf + prowler-prereqs: + files: + /home/ec2-user/.awsvariables: + content: !Sub | + export S3=s3://${S3} + export S3ACCOUNT=${S3Account} + export ROLE=${CrossAccountRole} + mode: "000600" + owner: ec2-user + group: ec2-user + commands: + 01-install-prowler-prereqs-yum: + command: | + yum install python-pip git jq -y + 02-install-prowler-prereqs-pip: + command: | + sudo -u ec2-user pip install --user boto3 awscli ansi2html detect-secrets + prowler-reports: + files: + # /home/ec2-user/run-prowler-reports-v4.sh: + # source: !Sub https://${S3}.s3.${AWS::Region}.amazonaws.com/run-prowler-reports-v4.sh + # mode: "000700" + # owner: ec2-user + # group: ec2-user + /home/ec2-user/run-prowler.sh: + content: | + #!/bin/bash -e + # + # Run Prowler against All AWS Accounts in an AWS Organization + + # Change Directory (rest of the script, assumes your in the ec2-user home directory) + cd /home/ec2-user + + # Download Prowler + rm -rf prowler + git clone https://github.com/toniblyx/prowler.git + + # Source .awsvariables (to read in Environment Variables from CloudFormation Data) + # shellcheck disable=SC1091 + source .awsvariables + + # Get Values from Environment Variables Created on EC2 Instance from CloudFormation Data + echo "S3: $S3" + echo "S3ACCOUNT: $S3ACCOUNT" + echo "ROLE: $ROLE" + + # Create Folder to Store Prowler Reports + mkdir -p prowler-reports + + # CleanUp Last Ran Prowler Reports + rm -rf prowler-reports/*.html + + # Function to unset AWS Profile Variables + unset_aws() { + unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN + } + unset_aws + + # Find THIS Account AWS Number + THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) + PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) + echo "THISACCOUNT: $THISACCOUNT" + echo "PARTITION: $PARTITION" + + # Function to Assume Role to THIS Account & Create Session + this_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$THISACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN + } + + # Find AWS Master Account + this_account_session + AWSMASTER=$(aws organizations describe-organization --query Organization.MasterAccountId --output text) + echo "AWSMASTER: $AWSMASTER" + + # Function to Assume Role to Master Account & Create Session + master_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$AWSMASTER":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN + } + + # Lookup All Accounts in AWS Organization + master_account_session + ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[*].Id --output text) + + # Function to Assume Role to S3 Account & Create Session + s3_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$S3ACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN + } + + # Run Prowler against Accounts in AWS Organization + echo "AWS Accounts in Organization" + echo "$ACCOUNTS_IN_ORGS" + for accountId in $ACCOUNTS_IN_ORGS; do + # Unset AWS Profile Variables + unset_aws + # Run Prowler + Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" + echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" + ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" + echo "Report stored locally at: $Report" + # Upload Prowler Report to S3 + s3_account_session + aws s3 cp "$Report" "$S3/reports/" + echo "" + done + + mode: "000700" + owner: ec2-user + group: ec2-user + + prowler-schedule: + files: + /home/ec2-user/prowlercron: + content: !Sub | + ${ProwlerCron} run-prowler-reports-v4.sh + mode: "000600" + owner: ec2-user + group: ec2-user + commands: + 01-create-prowler-cron-job: + command: | + sudo -u ec2-user crontab /home/ec2-user/prowlercron + + ProwlerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupName: Prowler-EC2-RemoteAdministration + GroupDescription: Allow Remote Administration + VpcId: !Ref VpcId + SecurityGroupIngress: + - Description: Allow SSH Administration + IpProtocol: tcp + FromPort: 22 + ToPort: 22 + SourcePrefixListId: pl-60b85b09 + SecurityGroupEgress: + - Description: Allow HTTP Outbound + IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + - Description: Allow HTTPS Outbound + IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + Metadata: + cfn_nag: + rules_to_suppress: + - id: W5 + reason: "Using http/https to Internet for updates." + - id: W28 + reason: "Using a defined Security Group Name." + + ProwlerInstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + Roles: + - !Ref ProwlerEc2Role + + ProwlerEc2Role: + Type: AWS::IAM::Role + Properties: + RoleName: !Ref Ec2Role + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: SSM-Agent + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowSsmAgent + Effect: Allow + Resource: "*" + Action: + - ssm:UpdateInstanceInformation + - ssm:ListInstanceAssociations + - ssm:UpdateInstanceAssociationStatus + - ssm:PutConfigurePackageResult + - ssm:GetManifest + - ssm:PutComplianceItems + - ec2messages:AcknowledgeMessage + - ec2messages:DeleteMessage + - ec2messages:FailMessage + - ec2messages:GetEndpoint + - ec2messages:GetMessages + - ec2messages:SendReply + - PolicyName: SSM-Inventory + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowPutInventory + Effect: Allow + Resource: "*" + Action: + - ssm:PutInventory + - Sid: AllowGatherInventory + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}::document/AWS-GatherSoftwareInventory + Action: + - ssm:GetDocument + - ssm:DescribeDocument + - PolicyName: SSM-SessionManager + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowSessionManager + Effect: Allow + Resource: "*" + Action: + - ssmmessages:CreateControlChannel + - ssmmessages:CreateDataChannel + - ssmmessages:OpenControlChannel + - ssmmessages:OpenDataChannel + - PolicyName: Prowler-S3-Reports + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Resource: + - !Sub arn:${AWS::Partition}:s3:::${S3} + - !Sub arn:${AWS::Partition}:s3:::${S3}/* + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + - PolicyName: Prowler-CrossAccount-AssumeRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowStsAssumeRole + Effect: Allow + Resource: !Sub arn:${AWS::Partition}:iam::*:role/${CrossAccountRole} + Action: sts:AssumeRole + Condition: + StringEquals: + aws:PrincipalOrgId: !Ref AwsOrgId + Metadata: + cfn_nag: + rules_to_suppress: + - id: W28 + reason: "Using a defined Role Name." + - id: W11 + reason: "Needed for SSM features." + +Outputs: + ProwlerEc2Account: + Description: AWS Account where Prowler EC2 resides + Value: !Ref AWS::AccountId + ProwlerEc2Role: + Description: Prowler EC2 Instance Role + Value: !Ref ProwlerEc2Role + ProwlerS3: + Description: S3 Bucket for Prowler Reports + Value: !Ref S3 diff --git a/util/org-multi-account/ProwlerRole.yaml b/util/org-multi-account/ProwlerRole.yaml new file mode 100644 index 00000000..0ca8997d --- /dev/null +++ b/util/org-multi-account/ProwlerRole.yaml @@ -0,0 +1,116 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create the Cross-Account IAM Prowler Role + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: EC2 Settings + Parameters: + - Ec2Account + - Ec2Role + - Label: + default: S3 Settings + Parameters: + - S3 + - Label: + default: CrossAccount Role + Parameters: + - CrossAccountRole + +Parameters: + S3: + Type: String + Description: Enter S3 Bucket to grant rights to EC2 Instance + Default: prowler-417425889548-us-east-1 + Ec2Account: + Type: String + Description: Enter AWS Account Number where EC2 Instance resides + AllowedPattern: ^\d{12}$ + ConstraintDescription: An AWS Account Number must be a 12 digit numeric string. + Default: 544425379660 + Ec2Role: + Type: String + Description: Enter Instance Role given to EC2 Instance (to grant sts:AssumeRole rights). + Default: ProwlerEC2-Role + CrossAccountRole: + Type: String + Description: Enter Name for CrossAccount Role to be created + Default: ProwlerXA-Role + +Resources: + ProwlerRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Ref CrossAccountRole + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: + # - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} + - !Sub arn:${AWS::Partition}:iam::${Ec2Account}:root + Action: + - sts:AssumeRole + Condition: + StringLike: + aws:PrincipalArn: !Sub arn:${AWS::Partition}:iam::${Ec2Account}:role/${Ec2Role} + ManagedPolicyArns: + - !Sub arn:${AWS::Partition}:iam::aws:policy/SecurityAudit + - !Sub arn:${AWS::Partition}:iam::aws:policy/job-function/ViewOnlyAccess + Policies: + - PolicyName: Prowler-Additions-Policy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowMoreReadForProwler + Effect: Allow + Resource: "*" + Action: + - access-analyzer:List* + - apigateway:Get* + - apigatewayv2:Get* + - aws-marketplace:ViewSubscriptions + - dax:ListTables + - ds:ListAuthorizedApplications + - ds:DescribeRoles + - ec2:GetEbsEncryptionByDefault + - ecr:Describe* + - lambda:GetAccountSettings + - lambda:GetFunctionConfiguration + - lambda:GetLayerVersionPolicy + - lambda:GetPolicy + - opsworks-cm:Describe* + - opsworks:Describe* + - secretsmanager:ListSecretVersionIds + - sns:List* + - sqs:ListQueueTags + - states:ListActivities + - support:Describe* + - tag:GetTagKeys + - PolicyName: Prowler-S3-Reports + PolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Resource: + - !Sub arn:${AWS::Partition}:s3:::${S3} + - !Sub arn:${AWS::Partition}:s3:::${S3}/* + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + Metadata: + cfn_nag: + rules_to_suppress: + - id: W11 + reason: "Prowler requires these rights to perform its Security Assessment." + - id: W28 + reason: "Using a defined Role Name." + +Outputs: + ProwlerCrossAccountRole: + Description: Prowler CrossAccount Role + Value: !Ref CrossAccountRole diff --git a/util/org-multi-account/ProwlerS3.yaml b/util/org-multi-account/ProwlerS3.yaml new file mode 100644 index 00000000..e30eab9f --- /dev/null +++ b/util/org-multi-account/ProwlerS3.yaml @@ -0,0 +1,72 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Create Prowler S3 Bucket for Prowler Reports + +Parameters: + AwsOrgId: + Type: String + Description: Enter AWS Organizations ID. This is used to restrict permissions to least privilege. + AllowedPattern: ^o-[a-z0-9]{10,32}$ + ConstraintDescription: The Org Id must be a 12 character string starting with o- and followed by 10 lower case alphanumeric characters. + Default: o-nbfb46ay7u + S3Prefix: + Type: String + Description: > + Enter S3 Bucket Name Prefix (in lowercase). + Bucket will be named: prefix-accountid-region + Default: prowler + +Resources: + ProwlerS3: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub ${S3Prefix}-${AWS::AccountId}-${AWS::Region} + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: "AES256" + AccessControl: Private + PublicAccessBlockConfiguration: + BlockPublicAcls: True + BlockPublicPolicy: True + IgnorePublicAcls: True + RestrictPublicBuckets: True + VersioningConfiguration: + Status: Enabled + Metadata: + cfn_nag: + rules_to_suppress: + - id: W35 + reason: "This S3 Bucket is only being used by the AWS Organization to download/upload prowler reports." + + ProwlerS3BucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref ProwlerS3 + PolicyDocument: + Statement: + - Sid: AllowGetPutListObject + Effect: Allow + Principal: "*" + Action: + - s3:GetObject + - s3:PutObject + - s3:ListBucket + Resource: + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3} + - !Sub arn:${AWS::Partition}:s3:::${ProwlerS3}/* + Condition: + StringEquals: + aws:PrincipalOrgId: !Ref AwsOrgId + Metadata: + cfn_nag: + rules_to_suppress: + - id: F16 + reason: "This S3 Bucket Policy has a condition that only allows access to the AWS Organization." + +Outputs: + ProwlerS3: + Description: S3 Bucket for Prowler Reports + Value: !Ref ProwlerS3 + ProwlerS3Account: + Description: AWS Account Number where S3 Resides + Value: !Ref AWS::AccountId diff --git a/util/org-multi-account/src/run-prowler-reports-v4.sh b/util/org-multi-account/src/run-prowler-reports-v4.sh new file mode 100644 index 00000000..4fc05b6c --- /dev/null +++ b/util/org-multi-account/src/run-prowler-reports-v4.sh @@ -0,0 +1,93 @@ +#!/bin/bash -e +# +# Run Prowler against All AWS Accounts in an AWS Organization + +# Change Directory (rest of the script, assumes your in the ec2-user home directory) +cd /home/ec2-user + +# Download Prowler +rm -rf prowler +git clone https://github.com/toniblyx/prowler.git + +# Source .awsvariables (to read in Environment Variables from CloudFormation Data) +# shellcheck disable=SC1091 +source .awsvariables + +# Get Values from Environment Variables Created on EC2 Instance from CloudFormation Data +echo "S3: $S3" +echo "S3ACCOUNT: $S3ACCOUNT" +echo "ROLE: $ROLE" + +# Create Folder to Store Prowler Reports +mkdir -p prowler-reports + +# CleanUp Last Ran Prowler Reports +rm -rf prowler-reports/*.html + +# Function to unset AWS Profile Variables +unset_aws() { + unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN +} +unset_aws + +# Find THIS Account AWS Number +THISACCOUNT=$(aws sts get-caller-identity --output text --query Account) +PARTITION=$(aws sts get-caller-identity --output text --query Arn | cut -d: -f2) +echo "THISACCOUNT: $THISACCOUNT" +echo "PARTITION: $PARTITION" + +# Function to Assume Role to THIS Account & Create Session +this_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$THISACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN +} + +# Find AWS Master Account +this_account_session +AWSMASTER=$(aws organizations describe-organization --query Organization.MasterAccountId --output text) +echo "AWSMASTER: $AWSMASTER" + +# Function to Assume Role to Master Account & Create Session +master_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$AWSMASTER":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN +} + +# Lookup All Accounts in AWS Organization +master_account_session +ACCOUNTS_IN_ORGS=$(aws organizations list-accounts --query Accounts[*].Id --output text) + +# Function to Assume Role to S3 Account & Create Session +s3_account_session() { + unset_aws + role_credentials=$(aws sts assume-role --role-arn arn:"$PARTITION":iam::"$S3ACCOUNT":role/"$ROLE" --role-session-name ProwlerRun --output json) + AWS_ACCESS_KEY_ID=$(echo "$role_credentials" | jq -r .Credentials.AccessKeyId) + AWS_SECRET_ACCESS_KEY=$(echo "$role_credentials" | jq -r .Credentials.SecretAccessKey) + AWS_SESSION_TOKEN=$(echo "$role_credentials" | jq -r .Credentials.SessionToken) + export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN +} + +# Run Prowler against Accounts in AWS Organization +echo "AWS Accounts in Organization" +echo "$ACCOUNTS_IN_ORGS" +for accountId in $ACCOUNTS_IN_ORGS; do + # Unset AWS Profile Variables + unset_aws + # Run Prowler + Report="prowler-reports/$(date +'%Y-%m-%d-%H%M%P')-$accountId-report.html" + echo -e "Analyzing AWS Account: $accountId, using Role: $ROLE" + ./prowler/prowler -R "$ROLE" -A "$accountId" -c check29 | ansi2html -la >"$Report" + echo "Report stored locally at: $Report" + # Upload Prowler Report to S3 + s3_account_session + aws s3 cp "$Report" "$S3/reports/" + echo "" +done