mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
tests v2
This commit is contained in:
12
include/check11
Normal file
12
include/check11
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CHECK_ID[check11]="1.1,1.01"
|
||||
CHECK_TITLE[check11]="Avoid the use of the root account (Scored)."
|
||||
CHECK_SCORED[check11]="SCORED"
|
||||
check11() {
|
||||
# "Avoid the use of the root account (Scored)."
|
||||
COMMAND11=$(cat $TEMP_REPORT_FILE| grep '<root_account>' | cut -d, -f5,11,16 | sed 's/,/\ /g')
|
||||
textTitle "$CHECK_ID" "$CHECK_TITLE" "SCORED" "LEVEL1"
|
||||
textNotice "Root account last accessed (password key_1 key_2): $COMMAND11"
|
||||
}
|
||||
CHECK_ALTERNATE[check101]="check11"
|
||||
8
include/group1
Normal file
8
include/group1
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GROUP_ID[1]="group1"
|
||||
GROUP_NUMBER[1]="1.0"
|
||||
GROUP_TITLE[1]="Identity and Access Management"
|
||||
GROUP_RUN_BY_DEFAULT[1]="Y"
|
||||
GROUP_CHECKS[1]="check11"
|
||||
textTitle "$GROUP_NUMBER" "$GROUP_TITLE"
|
||||
625
prowler2
Executable file
625
prowler2
Executable file
@@ -0,0 +1,625 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prowler is a tool that provides automate auditing and hardening guidance of an AWS account.
|
||||
# It is based on AWS-CLI commands. It follows guidelines present in the CIS Amazon
|
||||
# Web Services Foundations Benchmark at:
|
||||
# https://d0.awsstatic.com/whitepapers/compliance/AWS_CIS_Foundations_Benchmark.pdf
|
||||
|
||||
# This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0
|
||||
# International Public License. The link to the license terms can be found at
|
||||
# https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
||||
#
|
||||
# Author: Toni de la Fuente - @ToniBlyx - https://blyx.com/contact
|
||||
|
||||
# Prowler - Iron Maiden
|
||||
#
|
||||
# Walking through the city, looking oh so pretty
|
||||
# I've just got to find my way
|
||||
# See the ladies flashing
|
||||
# All there legs and lashes
|
||||
# I've just got to find my way...
|
||||
|
||||
OPTRED="[1;31m"
|
||||
OPTNORMAL="[0;39m"
|
||||
|
||||
# Set the defaults for these getopts variables
|
||||
REGION="us-east-1"
|
||||
FILTERREGION=""
|
||||
MAXITEMS=100
|
||||
MONOCHROME=0
|
||||
MODE="text"
|
||||
SEP=','
|
||||
KEEPCREDREPORT=0
|
||||
EXITCODE=0
|
||||
|
||||
# Command usage menu
|
||||
usage(){
|
||||
echo "
|
||||
USAGE:
|
||||
`basename $0` -p <profile> -r <region> [ -h ]
|
||||
|
||||
Options:
|
||||
-p <profile> specify your AWS profile to use (i.e.: default)
|
||||
-r <region> specify an AWS region to direct API requests to
|
||||
(i.e.: us-east-1), all regions are checked anyway
|
||||
-c <check_id> specify a check number or group from the AWS CIS benchmark
|
||||
(i.e.: "check11" for check 1.1, "check3" for entire section 3, "level1" for CIS Level 1 Profile Definitions or "forensics-ready")
|
||||
-f <filterregion> specify an AWS region to run checks against
|
||||
(i.e.: us-west-1)
|
||||
-m <maxitems> specify the maximum number of items to return for long-running requests (default: 100)
|
||||
-M <mode> output mode: text (defalut), mono, csv (separator is ","; data is on stdout; progress on stderr)
|
||||
-k keep the credential report
|
||||
-n show check numbers to sort easier
|
||||
(i.e.: 1.01 instead of 1.1)
|
||||
-l list all available checks only (does not perform any check)
|
||||
-e exclude extras
|
||||
-h this help
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
while getopts ":hlkp:r:c:f:m:M:en" OPTION; do
|
||||
case $OPTION in
|
||||
h )
|
||||
usage
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
;;
|
||||
l )
|
||||
PRINTCHECKSONLY=1
|
||||
;;
|
||||
k )
|
||||
KEEPCREDREPORT=1
|
||||
;;
|
||||
p )
|
||||
PROFILE=$OPTARG
|
||||
;;
|
||||
r )
|
||||
REGION=$OPTARG
|
||||
;;
|
||||
c )
|
||||
CHECKNUMBER=$OPTARG
|
||||
;;
|
||||
f )
|
||||
FILTERREGION=$OPTARG
|
||||
;;
|
||||
m )
|
||||
MAXITEMS=$OPTARG
|
||||
;;
|
||||
M )
|
||||
MODE=$OPTARG
|
||||
;;
|
||||
n )
|
||||
NUMERAL=1
|
||||
;;
|
||||
e )
|
||||
EXTRAS=1
|
||||
;;
|
||||
: )
|
||||
echo ""
|
||||
echo "$OPTRED ERROR!$OPTNORMAL -$OPTARG requires an argument"
|
||||
usage
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
;;
|
||||
? )
|
||||
echo ""
|
||||
echo "$OPTRED ERROR!$OPTNORMAL Invalid option"
|
||||
usage
|
||||
EXITCODE=1
|
||||
exit $EXITCODE
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# Get a list of all available AWS Regions
|
||||
REGIONS=$($AWSCLI ec2 describe-regions --query 'Regions[].RegionName' \
|
||||
--output text \
|
||||
$PROFILE_OPT \
|
||||
--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
|
||||
check11|check101 ) execute_check check11;;
|
||||
* )
|
||||
textWarn "ERROR! Use a valid check name (i.e. check41 or extra71)\n";
|
||||
esac
|
||||
cleanTemp
|
||||
exit $EXITCODE
|
||||
fi
|
||||
}
|
||||
|
||||
# List only check tittles
|
||||
|
||||
if [[ $PRINTCHECKSONLY == "1" ]]; then
|
||||
prowlerBanner
|
||||
show_all_titles
|
||||
exit $EXITCODE
|
||||
fi
|
||||
|
||||
# Data Structures
|
||||
#
|
||||
# Groups
|
||||
# ------
|
||||
# GROUP_NAME[X] = "groupname"
|
||||
# GROUP_TITLE[X] = "Logging *****"
|
||||
# GROUP_RUN_BY_DEFAULT[X] = "Y" // Whether this group is run by default
|
||||
# GROUP_CHECKS[X] = "check11,check12" // etc. etc.
|
||||
#
|
||||
# Checks & Extras
|
||||
# ---------------
|
||||
# CHECK_TITLE[checkname] = "Title checkname"
|
||||
# CHECK_ID[checkname] = '1.1,1.01'
|
||||
# CHECK_SCORED[checkname] = 'SCORED' or 'NOT_SCORED'
|
||||
# checkname() {
|
||||
# // code of the function. The function should be named checkname
|
||||
# }
|
||||
#
|
||||
# Check alternate names
|
||||
# CHECK_ALTERNATE[alternatename] = "checkname"
|
||||
# CHECK_ALTERNATE["check101"] = "check11"
|
||||
|
||||
# # For group of checks arrays
|
||||
# declare -a GROUP_NAME
|
||||
# declare -a GROUP_TITLE
|
||||
# declare -a GROUP_RUN_BY_DEFAULT
|
||||
# declare -a GROUP_CHECKS
|
||||
#
|
||||
# # For checks
|
||||
# declare -a CHECK_TITLE
|
||||
# declare -a CHECK_ID
|
||||
# declare -a CHECK_SCORED
|
||||
# declare -a CHECK_ALTERNATE
|
||||
|
||||
# Include all of the groups of checks inside include folder
|
||||
for group in $(ls include/group*); do
|
||||
. "$group"
|
||||
done
|
||||
|
||||
# Include all of the checks inside include folder
|
||||
# this includes also extra check since they are "check_extraNN"
|
||||
for checks in $(ls include/check*); do
|
||||
. "$checks"
|
||||
done
|
||||
|
||||
# Function to show the title of the check
|
||||
show_check_title() {
|
||||
# This would just call textTitle
|
||||
textTitle "${CHECK_ID[$1]} ${CHECK_TITLE[$1]} ${CHECK_SCORED[$1]}"
|
||||
}
|
||||
|
||||
# Function to show the title of a group, by numeric id
|
||||
show_group_title() {
|
||||
# This would also just call textTitle in the real prowler
|
||||
textTitle ${GROUP_NUMBER[$1]} - ${GROUP_TITLE[$1]}
|
||||
}
|
||||
|
||||
# Function to execute the check
|
||||
execute_check() {
|
||||
# See if this is an alternate name for a check
|
||||
# for example, we might have been passed 1.01 which is another name for 1.1
|
||||
if [ ${CHECK_ALTERNATE[$1]} ];then
|
||||
show_check_title ${CHECK_ALTERNATE[$1]}
|
||||
${CHECK_ALTERNATE[$1]}
|
||||
else
|
||||
show_check_title $1
|
||||
$1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to execute all checks in a group
|
||||
execute_group() {
|
||||
show_group_title $1
|
||||
# run the checks in the group
|
||||
IFS=',' read -ra CHECKS <<< ${GROUP_CHECKS[$1]}
|
||||
for i in "${CHECKS[@]}"; do
|
||||
execute_check $i
|
||||
done
|
||||
}
|
||||
|
||||
# Function to execute group by name
|
||||
execute_group_by_name() {
|
||||
for i in ${#GROUP_NAME[@]}; do
|
||||
if [ "${GROUP_NAME[$i]}" == "$1" ]; then
|
||||
execute_group $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Function to execute all checks in all groups
|
||||
execute_all() {
|
||||
for i in ${#GROUP_TITLE[@]}; do
|
||||
execute_group $i
|
||||
done
|
||||
}
|
||||
|
||||
# Function to show the titles of everything
|
||||
show_all_titles() {
|
||||
for i in ${#GROUP_TITLE[@]}; do
|
||||
show_group_title $i
|
||||
# Display the title of the checks
|
||||
IFS=',' read -ra CHECKS <<< ${GROUP_CHECKS[$i]}
|
||||
for j in "${CHECKS[@]}"; do
|
||||
show_check_title $j
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
### All functions defined above ... run the workflow
|
||||
|
||||
if [[ $MODE != "csv" ]]; then
|
||||
prowlerBanner
|
||||
printColorsCode
|
||||
fi
|
||||
getWhoami
|
||||
genCredReport
|
||||
saveReport
|
||||
callCheck
|
||||
|
||||
execute_all
|
||||
|
||||
|
||||
if [[ ! $EXTRAS ]]; then
|
||||
textTitle "7" "$TITLE7" "NOT_SCORED" "SUPPORT"
|
||||
execute_group 7
|
||||
fi
|
||||
|
||||
cleanTemp
|
||||
exit $EXITCODE
|
||||
Reference in New Issue
Block a user