mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
create check files
This commit is contained in:
0
checks/check
Normal file
0
checks/check
Normal file
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CHECK_ID[check11]="1.1,1.01"
|
||||
CHECK_TITLE[check11]="Avoid the use of the root account (Scored)."
|
||||
CHECK_TITLE[check11]="Avoid the use of the root account (Scored)"
|
||||
CHECK_SCORED[check11]="SCORED"
|
||||
CHECK_TYPE[check11]="LEVEL1"
|
||||
CHECK_ALTERNATE[check101]="check11"
|
||||
|
||||
0
checks/check110
Normal file
0
checks/check110
Normal file
0
checks/check111
Normal file
0
checks/check111
Normal file
0
checks/check112
Normal file
0
checks/check112
Normal file
0
checks/check113
Normal file
0
checks/check113
Normal file
0
checks/check114
Normal file
0
checks/check114
Normal file
0
checks/check115
Normal file
0
checks/check115
Normal file
0
checks/check116
Normal file
0
checks/check116
Normal file
0
checks/check117
Normal file
0
checks/check117
Normal file
0
checks/check118
Normal file
0
checks/check118
Normal file
0
checks/check119
Normal file
0
checks/check119
Normal file
25
checks/check12
Normal file
25
checks/check12
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CHECK_ID[check12]="1.2,1.02"
|
||||
CHECK_TITLE[check12]="Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)"
|
||||
CHECK_SCORED[check12]="SCORED"
|
||||
CHECK_TYPE[check12]="LEVEL1"
|
||||
CHECK_ALTERNATE[check102]="check12"
|
||||
|
||||
check12(){
|
||||
# "Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)"
|
||||
# List users with password enabled
|
||||
COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4 }' |grep true | awk '{ print $1 }')
|
||||
COMMAND12=$(
|
||||
for i in $COMMAND12_LIST_USERS_WITH_PASSWORD_ENABLED; do
|
||||
cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$8 }' |grep "$i " |grep false | awk '{ print $1 }'
|
||||
done)
|
||||
textTitle "$ID12" "$TITLE12" "SCORED" "LEVEL1"
|
||||
if [[ $COMMAND12 ]]; then
|
||||
for u in $COMMAND12; do
|
||||
textWarn "User $u has Password enabled but MFA disabled"
|
||||
done
|
||||
else
|
||||
textOK "No users found with Password enabled and MFA disabled"
|
||||
fi
|
||||
}
|
||||
0
checks/check120
Normal file
0
checks/check120
Normal file
0
checks/check121
Normal file
0
checks/check121
Normal file
0
checks/check122
Normal file
0
checks/check122
Normal file
0
checks/check123
Normal file
0
checks/check123
Normal file
0
checks/check124
Normal file
0
checks/check124
Normal file
0
checks/check13
Normal file
0
checks/check13
Normal file
0
checks/check14
Normal file
0
checks/check14
Normal file
0
checks/check15
Normal file
0
checks/check15
Normal file
0
checks/check16
Normal file
0
checks/check16
Normal file
0
checks/check17
Normal file
0
checks/check17
Normal file
0
checks/check18
Normal file
0
checks/check18
Normal file
0
checks/check19
Normal file
0
checks/check19
Normal file
0
checks/check21
Normal file
0
checks/check21
Normal file
0
checks/check22
Normal file
0
checks/check22
Normal file
0
checks/check23
Normal file
0
checks/check23
Normal file
0
checks/check24
Normal file
0
checks/check24
Normal file
0
checks/check25
Normal file
0
checks/check25
Normal file
0
checks/check26
Normal file
0
checks/check26
Normal file
0
checks/check27
Normal file
0
checks/check27
Normal file
0
checks/check28
Normal file
0
checks/check28
Normal file
0
checks/check31
Normal file
0
checks/check31
Normal file
0
checks/check310
Normal file
0
checks/check310
Normal file
0
checks/check311
Normal file
0
checks/check311
Normal file
0
checks/check312
Normal file
0
checks/check312
Normal file
0
checks/check313
Normal file
0
checks/check313
Normal file
0
checks/check314
Normal file
0
checks/check314
Normal file
0
checks/check315
Normal file
0
checks/check315
Normal file
0
checks/check32
Normal file
0
checks/check32
Normal file
0
checks/check33
Normal file
0
checks/check33
Normal file
0
checks/check34
Normal file
0
checks/check34
Normal file
0
checks/check35
Normal file
0
checks/check35
Normal file
0
checks/check36
Normal file
0
checks/check36
Normal file
0
checks/check37
Normal file
0
checks/check37
Normal file
0
checks/check38
Normal file
0
checks/check38
Normal file
0
checks/check39
Normal file
0
checks/check39
Normal file
0
checks/check41
Normal file
0
checks/check41
Normal file
0
checks/check42
Normal file
0
checks/check42
Normal file
0
checks/check43
Normal file
0
checks/check43
Normal file
0
checks/check44
Normal file
0
checks/check44
Normal file
0
checks/check45
Normal file
0
checks/check45
Normal file
0
checks/check_extra71
Normal file
0
checks/check_extra71
Normal file
0
checks/check_extra710
Normal file
0
checks/check_extra710
Normal file
0
checks/check_extra711
Normal file
0
checks/check_extra711
Normal file
0
checks/check_extra712
Normal file
0
checks/check_extra712
Normal file
0
checks/check_extra713
Normal file
0
checks/check_extra713
Normal file
0
checks/check_extra714
Normal file
0
checks/check_extra714
Normal file
0
checks/check_extra715
Normal file
0
checks/check_extra715
Normal file
0
checks/check_extra716
Normal file
0
checks/check_extra716
Normal file
0
checks/check_extra717
Normal file
0
checks/check_extra717
Normal file
0
checks/check_extra718
Normal file
0
checks/check_extra718
Normal file
0
checks/check_extra719
Normal file
0
checks/check_extra719
Normal file
0
checks/check_extra72
Normal file
0
checks/check_extra72
Normal file
0
checks/check_extra720
Normal file
0
checks/check_extra720
Normal file
0
checks/check_extra721
Normal file
0
checks/check_extra721
Normal file
0
checks/check_extra722
Normal file
0
checks/check_extra722
Normal file
0
checks/check_extra723
Normal file
0
checks/check_extra723
Normal file
0
checks/check_extra73
Normal file
0
checks/check_extra73
Normal file
0
checks/check_extra74
Normal file
0
checks/check_extra74
Normal file
0
checks/check_extra75
Normal file
0
checks/check_extra75
Normal file
0
checks/check_extra76
Normal file
0
checks/check_extra76
Normal file
0
checks/check_extra77
Normal file
0
checks/check_extra77
Normal file
0
checks/check_extra78
Normal file
0
checks/check_extra78
Normal file
0
checks/check_extra79
Normal file
0
checks/check_extra79
Normal file
166
checks/list
Normal file
166
checks/list
Normal file
@@ -0,0 +1,166 @@
|
||||
_
|
||||
_ __ _ __ _____ _| | ___ _ __
|
||||
| '_ \| '__/ _ \ \ /\ / / |/ _ \ '__|
|
||||
| |_) | | | (_) \ V V /| | __/ |
|
||||
| .__/|_| \___/ \_/\_/ |_|\___|_|
|
||||
|_| CIS based AWS Account Hardening Tool
|
||||
|
||||
Date: Tue Mar 20 21:50:38 EDT 2018
|
||||
|
||||
1 Identity and Access Management ****************************************
|
||||
|
||||
1.1 Avoid the use of the root account (Scored).
|
||||
|
||||
1.2 Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password (Scored)
|
||||
|
||||
1.3 Ensure credentials unused for 90 days or greater are disabled (Scored)
|
||||
|
||||
1.4 Ensure access keys are rotated every 90 days or less (Scored)
|
||||
|
||||
1.5 Ensure IAM password policy requires at least one uppercase letter (Scored)
|
||||
|
||||
1.6 Ensure IAM password policy require at least one lowercase letter (Scored)
|
||||
|
||||
1.7 Ensure IAM password policy require at least one symbol (Scored)
|
||||
|
||||
1.8 Ensure IAM password policy require at least one number (Scored)
|
||||
|
||||
1.9 Ensure IAM password policy requires minimum length of 14 or greater (Scored)
|
||||
|
||||
1.10 Ensure IAM password policy prevents password reuse: 24 or greater (Scored)
|
||||
|
||||
1.11 Ensure IAM password policy expires passwords within 90 days or less (Scored)
|
||||
|
||||
1.12 Ensure no root account access key exists (Scored)
|
||||
|
||||
1.13 Ensure MFA is enabled for the root account (Scored)
|
||||
|
||||
1.14 Ensure hardware MFA is enabled for the root account (Scored)
|
||||
|
||||
1.15 Ensure security questions are registered in the AWS account (Not Scored)
|
||||
|
||||
1.16 Ensure IAM policies are attached only to groups or roles (Scored)
|
||||
|
||||
1.17 Enable detailed billing (Scored)
|
||||
|
||||
1.18 Ensure IAM Master and IAM Manager roles are active (Scored)
|
||||
|
||||
1.19 Maintain current contact details (Scored)
|
||||
|
||||
1.20 Ensure security contact information is registered (Scored)
|
||||
|
||||
1.21 Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)
|
||||
|
||||
1.22 Ensure a support role has been created to manage incidents with AWS Support (Scored)
|
||||
|
||||
1.23 Do not setup access keys during initial user setup for all IAM users that have a console password (Not Scored)
|
||||
|
||||
1.24 Ensure IAM policies that allow full "*:*" administrative privileges are not created (Scored)
|
||||
|
||||
2 Logging ***************************************************************
|
||||
|
||||
2.1 Ensure CloudTrail is enabled in all regions (Scored)
|
||||
|
||||
2.2 Ensure CloudTrail log file validation is enabled (Scored)
|
||||
|
||||
2.3 Ensure the S3 bucket CloudTrail logs to is not publicly accessible (Scored)
|
||||
|
||||
2.4 Ensure CloudTrail trails are integrated with CloudWatch Logs (Scored)
|
||||
|
||||
2.5 Ensure AWS Config is enabled in all regions (Scored)
|
||||
|
||||
2.6 Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket (Scored)
|
||||
|
||||
2.7 Ensure CloudTrail logs are encrypted at rest using KMS CMKs (Scored)
|
||||
|
||||
2.8 Ensure rotation for customer created CMKs is enabled (Scored)
|
||||
|
||||
3 Monitoring ************************************************************
|
||||
|
||||
3.1 Ensure a log metric filter and alarm exist for unauthorized API calls (Scored)
|
||||
|
||||
3.2 Ensure a log metric filter and alarm exist for Management Console sign-in without MFA (Scored)
|
||||
|
||||
3.3 Ensure a log metric filter and alarm exist for usage of root account (Scored)
|
||||
|
||||
3.4 Ensure a log metric filter and alarm exist for IAM policy changes (Scored)
|
||||
|
||||
3.5 Ensure a log metric filter and alarm exist for CloudTrail configuration changes (Scored)
|
||||
|
||||
3.6 Ensure a log metric filter and alarm exist for AWS Management Console authentication failures (Scored)
|
||||
|
||||
3.7 Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs (Scored)
|
||||
|
||||
3.8 Ensure a log metric filter and alarm exist for S3 bucket policy changes (Scored)
|
||||
|
||||
3.9 Ensure a log metric filter and alarm exist for AWS Config configuration changes (Scored)
|
||||
|
||||
3.10 Ensure a log metric filter and alarm exist for security group changes (Scored)
|
||||
|
||||
3.11 Ensure a log metric filter and alarm exist for changes to Network Access Control Lists (NACL) (Scored)
|
||||
|
||||
3.12 Ensure a log metric filter and alarm exist for changes to network gateways (Scored)
|
||||
|
||||
3.13 Ensure a log metric filter and alarm exist for route table changes (Scored)
|
||||
|
||||
3.14 Ensure a log metric filter and alarm exist for VPC changes (Scored)
|
||||
|
||||
3.15 Ensure appropriate subscribers to each SNS topic (Not Scored)
|
||||
|
||||
4 Networking ************************************************************
|
||||
|
||||
4.1 Ensure no security groups allow ingress from 0.0.0.0/0 to port 22 (Scored)
|
||||
|
||||
4.2 Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389 (Scored)
|
||||
|
||||
4.3 Ensure VPC Flow Logging is Enabled in all VPCs (Scored)
|
||||
|
||||
4.4 Ensure the default security group of every VPC restricts all traffic (Scored)
|
||||
|
||||
4.5 Ensure routing tables for VPC peering are "least access" (Not Scored)
|
||||
|
||||
7 Extras ****************************************************************
|
||||
|
||||
7.1 Ensure users with AdministratorAccess policy have MFA tokens enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.2 Ensure there are no EBS Snapshots set as Public (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.3 Ensure there are no S3 buckets open to the Everyone or Any AWS user (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.4 Ensure there are no Security Groups without ingress filtering being used (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.5 Ensure there are no Security Groups not being used (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.6 Ensure there are no EC2 AMIs set as Public (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.7 Ensure there are no ECR repositories set as Public (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.8 Ensure there are no Public Accessible RDS instances (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.9 Check for internet facing Elastic Load Balancers (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.10 Check for internet facing EC2 Instances (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.11 Check for Publicly Accessible Redshift Clusters (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.12 Check if Amazon Macie is enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.13 Check if GuardDuty is enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.14 Check if CloudFront distributions have logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.15 Check if Elasticsearch Service domains have logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.16 Check if Elasticsearch Service domains allow open access (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.17 Check if Elastic Load Balancers have logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.18 Check if S3 buckets have server access logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.19 Check if Route53 hosted zones are logging queries to CloudWatch Logs (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.20 Check if Lambda functions invoke API operations are being recorded by CloudTrail (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.21 Check if Redshift cluster has audit logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
|
||||
7.22 Check if API Gateway has logging enabled (Not Scored) (Not part of CIS benchmark)
|
||||
79
checks/lista
Normal file
79
checks/lista
Normal file
@@ -0,0 +1,79 @@
|
||||
check1
|
||||
check11
|
||||
check12
|
||||
check13
|
||||
check14
|
||||
check15
|
||||
check16
|
||||
check17
|
||||
check18
|
||||
check19
|
||||
check110
|
||||
check111
|
||||
check112
|
||||
check113
|
||||
check114
|
||||
check115
|
||||
check116
|
||||
check117
|
||||
check118
|
||||
check119
|
||||
check120
|
||||
check121
|
||||
check122
|
||||
check123
|
||||
check124
|
||||
check2
|
||||
check21
|
||||
check22
|
||||
check23
|
||||
check24
|
||||
check25
|
||||
check26
|
||||
check27
|
||||
check28
|
||||
check3
|
||||
check31
|
||||
check32
|
||||
check33
|
||||
check34
|
||||
check35
|
||||
check36
|
||||
check37
|
||||
check38
|
||||
check39
|
||||
check310
|
||||
check311
|
||||
check312
|
||||
check313
|
||||
check314
|
||||
check315
|
||||
check4
|
||||
check41
|
||||
check42
|
||||
check43
|
||||
check44
|
||||
check45
|
||||
check7
|
||||
check71
|
||||
check72
|
||||
check73
|
||||
check74
|
||||
check75
|
||||
check76
|
||||
check77
|
||||
check78
|
||||
check79
|
||||
check710
|
||||
check711
|
||||
check712
|
||||
check713
|
||||
check714
|
||||
check715
|
||||
check716
|
||||
check717
|
||||
check718
|
||||
check719
|
||||
check720
|
||||
check721
|
||||
check722
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
GROUP_ID[1]="group1"
|
||||
GROUP_NUMBER[1]="1.0"
|
||||
GROUP_TITLE[1]="Identity and Access Management"
|
||||
GROUP_RUN_BY_DEFAULT[1]="Y" # run it when execute_all is called
|
||||
GROUP_CHECKS[1]="check11"
|
||||
GROUP_TITLE[1]="Identity and Access Management ****************************************"
|
||||
GROUP_RUN_BY_DEFAULT[1]="Y" # run it when execute_all is called
|
||||
GROUP_CHECKS[1]="check11,check12"
|
||||
|
||||
0
groups/group2
Normal file
0
groups/group2
Normal file
0
groups/group3
Normal file
0
groups/group3
Normal file
0
groups/group4
Normal file
0
groups/group4
Normal file
0
groups/group_cislevel1
Normal file
0
groups/group_cislevel1
Normal file
0
groups/group_cislevel2
Normal file
0
groups/group_cislevel2
Normal file
0
groups/group_extras
Normal file
0
groups/group_extras
Normal file
0
groups/group_forensics
Normal file
0
groups/group_forensics
Normal file
22
include/aws_profile_loader
Normal file
22
include/aws_profile_loader
Normal file
@@ -0,0 +1,22 @@
|
||||
# It checks -p optoin first and use it as profile, if not -p provided then
|
||||
# check environment variables and if not, it checks and loads credentials from
|
||||
# instance profile (metadata server) if runs in an EC2 instance
|
||||
|
||||
if [[ $PROFILE ]]; then
|
||||
PROFILE_OPT="--profile $PROFILE"
|
||||
else
|
||||
# if Prowler runs insinde an AWS instance with IAM instance profile attached
|
||||
INSTANCE_PROFILE=$(curl -s -m 1 http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
if [[ $INSTANCE_PROFILE ]]; then
|
||||
AWS_ACCESS_KEY_ID=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} | grep AccessKeyId | cut -d':' -f2 | sed 's/[^0-9A-Z]*//g')
|
||||
AWS_SECRET_ACCESS_KEY_ID=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} | grep SecretAccessKey | cut -d':' -f2 | sed 's/[^0-9A-Za-z/+=]*//g')
|
||||
AWS_SESSION_TOKEN=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} grep Token| cut -d':' -f2 | sed 's/[^0-9A-Za-z/+=]*//g')
|
||||
fi
|
||||
if [[ $AWS_ACCESS_KEY_ID && $AWS_SECRET_ACCESS_KEY || $AWS_SESSION_TOKEN ]];then
|
||||
PROFILE="ENV"
|
||||
PROFILE_OPT=""
|
||||
else
|
||||
PROFILE="default"
|
||||
PROFILE_OPT="--profile $PROFILE"
|
||||
fi
|
||||
fi
|
||||
7
include/awscli_detector
Normal file
7
include/awscli_detector
Normal file
@@ -0,0 +1,7 @@
|
||||
# AWS-CLI detector variable
|
||||
AWSCLI=$(which aws)
|
||||
if [ -z "${AWSCLI}" ]; then
|
||||
echo -e "\n$RED ERROR!$NORMAL AWS-CLI (aws command) not found. Make sure it is installed correctly and in your \$PATH\n"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
19
include/banner
Normal file
19
include/banner
Normal file
@@ -0,0 +1,19 @@
|
||||
prowlerBanner() {
|
||||
echo -e "$CYAN _"
|
||||
echo -e " _ __ _ __ _____ _| | ___ _ __"
|
||||
echo -e " | '_ \| '__/ _ \ \ /\ / / |/ _ \ '__|"
|
||||
echo -e " | |_) | | | (_) \ V V /| | __/ |"
|
||||
echo -e " | .__/|_| \___/ \_/\_/ |_|\___|_|"
|
||||
echo -e " |_|$NORMAL$BLUE CIS based AWS Account Hardening Tool$NORMAL\n"
|
||||
echo -e "$YELLOW Date: $(date)"
|
||||
}
|
||||
|
||||
infoReferenceLong(){
|
||||
# Report review note:
|
||||
echo -e ""
|
||||
echo -e "For more information on the Prowler, feedback and issue reporting:"
|
||||
echo -e "https://github.com/toniblyx/prowler"
|
||||
echo -e ""
|
||||
echo -e "For more information on the CIS benchmark:"
|
||||
echo -e "https://benchmarks.cisecurity.org/tools2/amazon/CIS_Amazon_Web_Services_Foundations_Benchmark_v1.1.0.pdf"
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
if [[ $MODE != "mono" && $MODE != "text" && $MODE != "csv" ]]; then
|
||||
echo ""
|
||||
echo "$OPTRED ERROR!$OPTNORMAL Invalid output mode. Choose text, mono, or csv."
|
||||
usage
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
if [[ "$MODE" == "mono" || "$MODE" == "csv" ]]; then
|
||||
MONOCHROME=1
|
||||
fi
|
||||
|
||||
if [[ $MONOCHROME -eq 1 ]]; then
|
||||
# Colors
|
||||
NORMAL=''
|
||||
WARNING='' # Bad (red)
|
||||
SECTION='' # Section (yellow)
|
||||
NOTICE='' # Notice (yellow)
|
||||
OK='' # Ok (green)
|
||||
BAD='' # Bad (red)
|
||||
CYAN=''
|
||||
BLUE=''
|
||||
BROWN=''
|
||||
DARKGRAY=''
|
||||
GRAY=''
|
||||
GREEN=''
|
||||
MAGENTA=''
|
||||
PURPLE=''
|
||||
RED=''
|
||||
YELLOW=''
|
||||
WHITE=''
|
||||
else
|
||||
# Colors
|
||||
# NOTE: Your editor may NOT show the 0x1b / escape character left of the '['
|
||||
NORMAL="[0;39m"
|
||||
WARNING="[1;33m" # Bad (red)
|
||||
SECTION="[1;33m" # Section (yellow)
|
||||
NOTICE="[1;33m" # Notice (yellow)
|
||||
OK="[1;32m" # Ok (green)
|
||||
BAD="[1;31m" # Bad (red)
|
||||
CYAN="[0;36m"
|
||||
BLUE="[0;34m"
|
||||
BROWN="[0;33m"
|
||||
DARKGRAY="[0;30m"
|
||||
GRAY="[0;37m"
|
||||
GREEN="[1;32m"
|
||||
MAGENTA="[1;35m"
|
||||
PURPLE="[0;35m"
|
||||
RED="[1;31m"
|
||||
YELLOW="[1;33m"
|
||||
WHITE="[1;37m"
|
||||
fi
|
||||
|
||||
printColorsCode(){
|
||||
if [[ $MONOCHROME -eq 0 ]]; then
|
||||
echo -e "\n$NORMAL Colors Code for results: $NOTICE INFORMATIVE$NORMAL,$OK OK (RECOMMENDED VALUE)$NORMAL, $BAD WARNING (FIX REQUIRED)$NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
26
include/credentials_report
Normal file
26
include/credentials_report
Normal file
@@ -0,0 +1,26 @@
|
||||
# Generate Credential Report
|
||||
genCredReport() {
|
||||
textTitle "0.1" "Generating AWS IAM Credential Report..." "NOT_SCORED" "SUPPORT"
|
||||
until $( $AWSCLI iam generate-credential-report --output text --query 'State' $PROFILE_OPT --region $REGION |grep -q -m 1 "COMPLETE") ; do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Save report to a file, decode it, deletion at finish and after every single check
|
||||
saveReport(){
|
||||
$AWSCLI iam get-credential-report --query 'Content' --output text $PROFILE_OPT --region $REGION | decode_report > $TEMP_REPORT_FILE
|
||||
if [[ $KEEPCREDREPORT -eq 1 ]]; then
|
||||
textTitle "0.2" "Saving IAM Credential Report ..." "NOT_SCORED" "SUPPORT"
|
||||
textNotice "IAM Credential Report saved in $TEMP_REPORT_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Delete temporary report file
|
||||
cleanTemp(){
|
||||
if [[ $KEEPCREDREPORT -ne 1 ]]; then
|
||||
rm -fr $TEMP_REPORT_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
# Delete the temporary report file if we get interrupted/terminated
|
||||
trap cleanTemp EXIT
|
||||
5
include/csv_header
Normal file
5
include/csv_header
Normal file
@@ -0,0 +1,5 @@
|
||||
printCsvHeader() {
|
||||
>&2 echo ""
|
||||
>&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM"
|
||||
echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES"
|
||||
}
|
||||
76
include/os_detector
Normal file
76
include/os_detector
Normal file
@@ -0,0 +1,76 @@
|
||||
# Functions to manage dates depending on OS
|
||||
if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux-musl" ]; then
|
||||
TEMP_REPORT_FILE=$(mktemp -t -p /tmp prowler.cred_report-XXXXXX)
|
||||
# function to compare in days, usage how_older_from_today date
|
||||
# date format %Y-%m-%d
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date -d "$(date +%Y-%m-%d)" +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
# function to convert from timestamp to date, usage timestamp_to_date timestamp
|
||||
# output date format %Y-%m-%d
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -d @$TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -d
|
||||
}
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# BSD/OSX commands compatibility
|
||||
TEMP_REPORT_FILE=$(mktemp -t prowler.cred_report-XXXXXX)
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -jf %Y-%m-%d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -r $TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -D
|
||||
}
|
||||
elif [[ "$OSTYPE" == "cygwin" ]]; then
|
||||
# POSIX compatibility layer and Linux environment emulation for Windows
|
||||
TEMP_REPORT_FILE=$(mktemp -t -p /tmp prowler.cred_report-XXXXXX)
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date -d "$(date +%Y-%m-%d)" +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -d @$TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -d
|
||||
}
|
||||
else
|
||||
echo "Unknown Operating System! Valid \$OSTYPE: linux-gnu, linux-musl, darwin* or cygwin"
|
||||
echo "Found: $OSTYPE"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
81
include/outputs
Normal file
81
include/outputs
Normal file
@@ -0,0 +1,81 @@
|
||||
## Output formatting functions
|
||||
textOK(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $OK OK! $NORMAL $1"
|
||||
fi
|
||||
}
|
||||
|
||||
textNotice(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $NOTICE INFO! $1 $NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
textWarn(){
|
||||
EXITCODE=3
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}WARNING${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $BAD WARNING! $1 $NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
textTitle(){
|
||||
TITLE_ID=$1
|
||||
if [[ $NUMERAL ]]; then
|
||||
TITLE_ID=$(echo $TITLE_ID | cut -d, -f2)
|
||||
else
|
||||
TITLE_ID=$(echo $TITLE_ID | cut -d, -f1)
|
||||
fi
|
||||
|
||||
TITLE_TEXT=$2
|
||||
|
||||
case "$3" in
|
||||
0|No|NOT_SCORED)
|
||||
ITEM_SCORED="Not Scored"
|
||||
;;
|
||||
1|Yes|SCORED)
|
||||
ITEM_SCORED="Scored"
|
||||
;;
|
||||
*)
|
||||
ITEM_SCORED="Unspecified"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$4" in
|
||||
LEVEL1) ITEM_LEVEL="Level 1";;
|
||||
LEVEL2) ITEM_LEVEL="Level 2";;
|
||||
EXTRA) ITEM_LEVEL="Extra";;
|
||||
SUPPORT) ITEM_LEVEL="Support";;
|
||||
*) ITEM_LEVEL="Unspecified or Invalid";;
|
||||
esac
|
||||
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
>&2 echo "$TITLE_ID $TITLE_TEXT"
|
||||
else
|
||||
if [[ "$ITEM_SCORED" == "Scored" ]]; then
|
||||
echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT"
|
||||
else
|
||||
echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $NORMAL"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
44
include/whoami
Normal file
44
include/whoami
Normal file
@@ -0,0 +1,44 @@
|
||||
# Get whoami in AWS, who is the user running this shell script
|
||||
getWhoami(){
|
||||
ACCOUNT_NUM=$($AWSCLI sts get-caller-identity --output json $PROFILE_OPT --region $REGION --query "Account" | tr -d '"')
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
CALLER_ARN_RAW=$($AWSCLI sts get-caller-identity --output json $PROFILE_OPT --region $REGION --query "Arn")
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
EXITCODE=2
|
||||
exit $EXITCODE
|
||||
fi
|
||||
CALLER_ARN=$(echo $CALLER_ARN_RAW | tr -d '"')
|
||||
printCsvHeader
|
||||
textTitle "0.0" "Show report generation info" "NOT_SCORED" "SUPPORT"
|
||||
textNotice "ARN: $CALLER_ARN TIMESTAMP: $SCRIPT_START_TIME"
|
||||
else
|
||||
echo ""
|
||||
echo -e " This report is being generated using credentials below:\n"
|
||||
echo -e " AWS-CLI Profile: $NOTICE[$PROFILE]$NORMAL AWS API Region: $NOTICE[$REGION]$NORMAL AWS Filter Region: $NOTICE[${FILTERREGION:-all}]$NORMAL\n"
|
||||
if [[ $MONOCHROME -eq 1 ]]; then
|
||||
echo -e " Caller Identity:"
|
||||
$AWSCLI sts get-caller-identity --output text $PROFILE_OPT --region $REGION --query "Arn"
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
echo -e " Caller Identity:"
|
||||
$AWSCLI sts get-caller-identity --output table $PROFILE_OPT --region $REGION
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo variable $PROFILE_OPT
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
EXITCODE=2
|
||||
exit $EXITCODE
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
334
prowler2
334
prowler2
@@ -31,12 +31,15 @@ MODE="text"
|
||||
SEP=','
|
||||
KEEPCREDREPORT=0
|
||||
EXITCODE=0
|
||||
SCRIPT_START_TIME=$( date -u +"%Y-%m-%dT%H:%M:%S%z" )
|
||||
TITLE_ID=""
|
||||
TITLE_TEXT="CALLER ERROR - UNSET TITLE"
|
||||
|
||||
# Command usage menu
|
||||
usage(){
|
||||
echo "
|
||||
USAGE:
|
||||
`basename $0` -p <profile> -r <region> [ -h ]
|
||||
`basename $0` [ -p <profile> -r <region> -h ]
|
||||
|
||||
Options:
|
||||
-p <profile> specify your AWS profile to use (i.e.: default)
|
||||
@@ -53,12 +56,13 @@ USAGE:
|
||||
(i.e.: 1.01 instead of 1.1)
|
||||
-l list all available checks only (does not perform any check)
|
||||
-e exclude extras
|
||||
-b do not print Prowler banner
|
||||
-h this help
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
while getopts ":hlkp:r:c:f:m:M:en" OPTION; do
|
||||
while getopts ":hlkp:r:c:f:m:M:enb" OPTION; do
|
||||
case $OPTION in
|
||||
h )
|
||||
usage
|
||||
@@ -92,6 +96,9 @@ while getopts ":hlkp:r:c:f:m:M:en" OPTION; do
|
||||
n )
|
||||
NUMERAL=1
|
||||
;;
|
||||
b )
|
||||
NOBANNER="true"
|
||||
;;
|
||||
e )
|
||||
EXTRAS=1
|
||||
;;
|
||||
@@ -113,297 +120,14 @@ while getopts ":hlkp:r:c:f:m:M:en" OPTION; do
|
||||
done
|
||||
|
||||
. include/colors
|
||||
|
||||
SCRIPT_START_TIME=$( date -u +"%Y-%m-%dT%H:%M:%S%z" )
|
||||
|
||||
# Functions to manage dates depending on OS
|
||||
if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux-musl" ]; then
|
||||
TEMP_REPORT_FILE=$(mktemp -t -p /tmp prowler.cred_report-XXXXXX)
|
||||
# function to compare in days, usage how_older_from_today date
|
||||
# date format %Y-%m-%d
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date -d "$(date +%Y-%m-%d)" +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
# function to convert from timestamp to date, usage timestamp_to_date timestamp
|
||||
# output date format %Y-%m-%d
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -d @$TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -d
|
||||
}
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# BSD/OSX commands compatibility
|
||||
TEMP_REPORT_FILE=$(mktemp -t prowler.cred_report-XXXXXX)
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -jf %Y-%m-%d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -r $TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -D
|
||||
}
|
||||
elif [[ "$OSTYPE" == "cygwin" ]]; then
|
||||
# POSIX compatibility layer and Linux environment emulation for Windows
|
||||
TEMP_REPORT_FILE=$(mktemp -t -p /tmp prowler.cred_report-XXXXXX)
|
||||
how_older_from_today()
|
||||
{
|
||||
DATE_TO_COMPARE=$1
|
||||
TODAY_IN_DAYS=$(date -d "$(date +%Y-%m-%d)" +%s)
|
||||
DATE_FROM_IN_DAYS=$(date -d $DATE_TO_COMPARE +%s)
|
||||
DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24))
|
||||
echo $DAYS_SINCE
|
||||
}
|
||||
timestamp_to_date()
|
||||
{
|
||||
# remove fractions of a second
|
||||
TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".")
|
||||
OUTPUT_DATE=$(date -d @$TIMESTAMP_TO_CONVERT +'%Y-%m-%d')
|
||||
echo $OUTPUT_DATE
|
||||
}
|
||||
decode_report()
|
||||
{
|
||||
base64 -d
|
||||
}
|
||||
else
|
||||
echo "Unknown Operating System! Valid \$OSTYPE: linux-gnu, linux-musl, darwin* or cygwin"
|
||||
echo "Found: $OSTYPE"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
# It checks -p optoin first and use it as profile, if not -p provided then
|
||||
# check environment variables and if not, it checks and loads credentials from
|
||||
# instance profile (metadata server) if runs in an EC2 instance
|
||||
|
||||
if [[ $PROFILE ]]; then
|
||||
PROFILE_OPT="--profile $PROFILE"
|
||||
else
|
||||
# if Prowler runs insinde an AWS instance with IAM instance profile attached
|
||||
INSTANCE_PROFILE=$(curl -s -m 1 http://169.254.169.254/latest/meta-data/iam/security-credentials/)
|
||||
if [[ $INSTANCE_PROFILE ]]; then
|
||||
AWS_ACCESS_KEY_ID=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} | grep AccessKeyId | cut -d':' -f2 | sed 's/[^0-9A-Z]*//g')
|
||||
AWS_SECRET_ACCESS_KEY_ID=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} | grep SecretAccessKey | cut -d':' -f2 | sed 's/[^0-9A-Za-z/+=]*//g')
|
||||
AWS_SESSION_TOKEN=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${INSTANCE_PROFILE} grep Token| cut -d':' -f2 | sed 's/[^0-9A-Za-z/+=]*//g')
|
||||
fi
|
||||
if [[ $AWS_ACCESS_KEY_ID && $AWS_SECRET_ACCESS_KEY || $AWS_SESSION_TOKEN ]];then
|
||||
PROFILE="ENV"
|
||||
PROFILE_OPT=""
|
||||
else
|
||||
PROFILE="default"
|
||||
PROFILE_OPT="--profile $PROFILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# AWS-CLI variables
|
||||
AWSCLI=$(which aws)
|
||||
if [ -z "${AWSCLI}" ]; then
|
||||
echo -e "\n$RED ERROR!$NORMAL AWS-CLI (aws command) not found. Make sure it is installed correctly and in your \$PATH\n"
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
TITLE_ID=""
|
||||
TITLE_TEXT="CALLER ERROR - UNSET TITLE"
|
||||
|
||||
## Output formatting functions
|
||||
textOK(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $OK OK! $NORMAL $1"
|
||||
fi
|
||||
}
|
||||
|
||||
textNotice(){
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $NOTICE INFO! $1 $NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
textWarn(){
|
||||
EXITCODE=3
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
if [[ $2 ]]; then
|
||||
REPREGION=$2
|
||||
else
|
||||
REPREGION=$REGION
|
||||
fi
|
||||
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}WARNING${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1"
|
||||
else
|
||||
echo " $BAD WARNING! $1 $NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
textTitle(){
|
||||
TITLE_ID=$1
|
||||
if [[ $NUMERAL ]]; then
|
||||
TITLE_ID=$(echo $TITLE_ID | cut -d, -f2)
|
||||
else
|
||||
TITLE_ID=$(echo $TITLE_ID | cut -d, -f1)
|
||||
fi
|
||||
|
||||
TITLE_TEXT=$2
|
||||
|
||||
case "$3" in
|
||||
0|No|NOT_SCORED)
|
||||
ITEM_SCORED="Not Scored"
|
||||
;;
|
||||
1|Yes|SCORED)
|
||||
ITEM_SCORED="Scored"
|
||||
;;
|
||||
*)
|
||||
ITEM_SCORED="Unspecified"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$4" in
|
||||
LEVEL1) ITEM_LEVEL="Level 1";;
|
||||
LEVEL2) ITEM_LEVEL="Level 2";;
|
||||
EXTRA) ITEM_LEVEL="Extra";;
|
||||
SUPPORT) ITEM_LEVEL="Support";;
|
||||
*) ITEM_LEVEL="Unspecified or Invalid";;
|
||||
esac
|
||||
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
>&2 echo "$TITLE_ID $TITLE_TEXT"
|
||||
else
|
||||
if [[ "$ITEM_SCORED" == "Scored" ]]; then
|
||||
echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT"
|
||||
else
|
||||
echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $NORMAL"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
printCsvHeader() {
|
||||
>&2 echo ""
|
||||
>&2 echo "Generating \"${SEP}\" delimited report on stdout for profile $PROFILE, account $ACCOUNT_NUM"
|
||||
echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES"
|
||||
}
|
||||
|
||||
prowlerBanner() {
|
||||
echo -e "$CYAN _"
|
||||
echo -e " _ __ _ __ _____ _| | ___ _ __"
|
||||
echo -e " | '_ \| '__/ _ \ \ /\ / / |/ _ \ '__|"
|
||||
echo -e " | |_) | | | (_) \ V V /| | __/ |"
|
||||
echo -e " | .__/|_| \___/ \_/\_/ |_|\___|_|"
|
||||
echo -e " |_|$NORMAL$BLUE CIS based AWS Account Hardening Tool$NORMAL\n"
|
||||
echo -e "$YELLOW Date: $(date)"
|
||||
}
|
||||
|
||||
# Get whoami in AWS, who is the user running this shell script
|
||||
getWhoami(){
|
||||
ACCOUNT_NUM=$($AWSCLI sts get-caller-identity --output json $PROFILE_OPT --region $REGION --query "Account" | tr -d '"')
|
||||
if [[ "$MODE" == "csv" ]]; then
|
||||
CALLER_ARN_RAW=$($AWSCLI sts get-caller-identity --output json $PROFILE_OPT --region $REGION --query "Arn")
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
EXITCODE=2
|
||||
exit $EXITCODE
|
||||
fi
|
||||
CALLER_ARN=$(echo $CALLER_ARN_RAW | tr -d '"')
|
||||
printCsvHeader
|
||||
textTitle "0.0" "Show report generation info" "NOT_SCORED" "SUPPORT"
|
||||
textNotice "ARN: $CALLER_ARN TIMESTAMP: $SCRIPT_START_TIME"
|
||||
else
|
||||
echo ""
|
||||
echo "This report is being generated using credentials below:"
|
||||
echo ""
|
||||
echo -e "AWS-CLI Profile: $NOTICE[$PROFILE]$NORMAL AWS API Region: $NOTICE[$REGION]$NORMAL AWS Filter Region: $NOTICE[${FILTERREGION:-all}]$NORMAL\n"
|
||||
if [[ $MONOCHROME -eq 1 ]]; then
|
||||
echo "Caller Identity:"
|
||||
$AWSCLI sts get-caller-identity --output text $PROFILE_OPT --region $REGION --query "Arn"
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
exit 2
|
||||
fi
|
||||
echo ""
|
||||
else
|
||||
echo "Caller Identity:"
|
||||
$AWSCLI sts get-caller-identity --output table $PROFILE_OPT --region $REGION
|
||||
if [[ 255 -eq $? ]]; then
|
||||
# Failed to get own identity ... exit
|
||||
echo variable $PROFILE_OPT
|
||||
echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
>&2 echo "ERROR WITH $PROFILE CREDENTIALS - EXITING!"
|
||||
EXITCODE=2
|
||||
exit $EXITCODE
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
printColorsCode(){
|
||||
if [[ $MONOCHROME -eq 0 ]]; then
|
||||
echo -e "\nColors Code for results: $NOTICE INFORMATIVE$NORMAL,$OK OK (RECOMMENDED VALUE)$NORMAL, $BAD WARNING (FIX REQUIRED)$NORMAL \n"
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate Credential Report
|
||||
genCredReport() {
|
||||
textTitle "0.1" "Generating AWS IAM Credential Report..." "NOT_SCORED" "SUPPORT"
|
||||
until $( $AWSCLI iam generate-credential-report --output text --query 'State' $PROFILE_OPT --region $REGION |grep -q -m 1 "COMPLETE") ; do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Save report to a file, decode it, deletion at finish and after every single check
|
||||
saveReport(){
|
||||
$AWSCLI iam get-credential-report --query 'Content' --output text $PROFILE_OPT --region $REGION | decode_report > $TEMP_REPORT_FILE
|
||||
if [[ $KEEPCREDREPORT -eq 1 ]]; then
|
||||
textTitle "0.2" "Saving IAM Credential Report ..." "NOT_SCORED" "SUPPORT"
|
||||
textNotice "IAM Credential Report saved in $TEMP_REPORT_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Delete temporary report file
|
||||
cleanTemp(){
|
||||
if [[ $KEEPCREDREPORT -ne 1 ]]; then
|
||||
rm -fr $TEMP_REPORT_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
# Delete the temporary report file if we get interrupted/terminated
|
||||
trap cleanTemp EXIT
|
||||
. include/os_detector
|
||||
. include/aws_profile_loader
|
||||
. include/awscli_detector
|
||||
. include/outputs
|
||||
. include/csv_header
|
||||
. include/banner
|
||||
. include/whoami
|
||||
. include/credentials_report
|
||||
|
||||
# Get a list of all available AWS Regions
|
||||
REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' \
|
||||
@@ -412,17 +136,6 @@ REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' \
|
||||
--region $REGION \
|
||||
--region-names $FILTERREGION)
|
||||
|
||||
infoReferenceLong(){
|
||||
# Report review note:
|
||||
echo -e ""
|
||||
echo -e "For more information on the Prowler, feedback and issue reporting:"
|
||||
echo -e "https://github.com/Alfresco/prowler"
|
||||
echo -e ""
|
||||
echo -e "For more information on the CIS benchmark:"
|
||||
echo -e "https://benchmarks.cisecurity.org/tools2/amazon/CIS_Amazon_Web_Services_Foundations_Benchmark_v1.1.0.pdf"
|
||||
|
||||
}
|
||||
|
||||
callCheck(){
|
||||
if [[ $CHECKNUMBER ]];then
|
||||
case "$CHECKNUMBER" in
|
||||
@@ -436,20 +149,19 @@ callCheck(){
|
||||
}
|
||||
|
||||
# List only check tittles
|
||||
|
||||
if [[ $PRINTCHECKSONLY == "1" ]]; then
|
||||
prowlerBanner
|
||||
show_all_titles
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
# Include all of the groups of checks inside include folder
|
||||
# Load all of the groups of checks inside groups folder named as "group*"
|
||||
for group in $(ls groups/group*); do
|
||||
. "$group"
|
||||
done
|
||||
|
||||
# Include all of the checks inside include folder
|
||||
# this includes also extra check since they are "check_extraNN"
|
||||
# Load all of the checks inside checks folder named as "check*"
|
||||
# this includes also extra checks since they are "check_extraNN"
|
||||
for checks in $(ls checks/check*); do
|
||||
. "$checks"
|
||||
done
|
||||
@@ -462,7 +174,7 @@ show_check_title() {
|
||||
|
||||
# Function to show the title of a group, by numeric id
|
||||
show_group_title() {
|
||||
# This would also just call textTitle in the real prowler
|
||||
# when csv mode is used, no group tittle is shown
|
||||
if [[ "$MODE" != "csv" ]]; then
|
||||
textTitle "${GROUP_NUMBER[$1]}" "${GROUP_TITLE[$1]}" "NOT_SCORED" "SUPPORT"
|
||||
fi
|
||||
@@ -523,7 +235,7 @@ show_all_titles() {
|
||||
|
||||
### All functions defined above ... run the workflow
|
||||
|
||||
if [[ $MODE != "csv" ]]; then
|
||||
if [[ $MODE != "csv" || $NOBANNER != "true" ]]; then
|
||||
prowlerBanner
|
||||
printColorsCode
|
||||
fi
|
||||
@@ -532,7 +244,7 @@ genCredReport
|
||||
saveReport
|
||||
callCheck
|
||||
|
||||
show_all_titles
|
||||
execute_all
|
||||
|
||||
|
||||
# if [[ ! $EXTRAS ]]; then
|
||||
|
||||
Reference in New Issue
Block a user