Merge branch 'master' into master

This commit is contained in:
Toni de la Fuente
2020-12-18 10:24:25 +01:00
committed by GitHub
73 changed files with 626 additions and 156 deletions

View File

@@ -31,13 +31,13 @@ assume_role(){
# assume role command
$AWSCLI $PROFILE_OPT sts assume-role --role-arn arn:${AWS_PARTITION}:iam::$ACCOUNT_TO_ASSUME:role/$ROLE_TO_ASSUME \
--role-session-name ProwlerAssessmentSession \
--region $REGION \
--region $REGION_FOR_STS \
--duration-seconds $SESSION_DURATION_TO_ASSUME > $TEMP_STS_ASSUMED_FILE
else
$AWSCLI $PROFILE_OPT sts assume-role --role-arn arn:${AWS_PARTITION}:iam::$ACCOUNT_TO_ASSUME:role/$ROLE_TO_ASSUME \
--role-session-name ProwlerAssessmentSession \
--duration-seconds $SESSION_DURATION_TO_ASSUME \
--region $REGION \
--region $REGION_FOR_STS \
--external-id $ROLE_EXTERNAL_ID > $TEMP_STS_ASSUMED_FILE
fi
@@ -64,6 +64,7 @@ assume_role(){
export AWS_ACCESS_KEY_ID=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.SessionToken')
export AWS_SESSION_EXPIRATION=$(convert_date_to_timestamp "$(cat $TEMP_STS_ASSUMED_FILE | jq -r '.Credentials.Expiration')")
rm -fr $TEMP_STS_ASSUMED_FILE
}

View File

@@ -39,6 +39,8 @@ elif [[ $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')
elif [[ $AWS_EXECUTION_ENV == "CloudShell" ]]; then
PROFILE_OPT=""
else
PROFILE="default"
PROFILE_OPT="--profile $PROFILE"

View File

@@ -15,5 +15,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" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
echo "PROFILE${SEP}ACCOUNT_NUM${SEP}REGION${SEP}TITLE_ID${SEP}RESULT${SEP}SCORED${SEP}LEVEL${SEP}TITLE_TEXT${SEP}NOTES${SEP}COMPLIANCE" | tee -a $OUTPUT_FILE_NAME.$EXTENSION_CSV
}

View File

@@ -100,6 +100,7 @@ addHtmlHeader() {
<th scope="col">Result</th>
<th scope="col">AccountID</th>
<th scope="col">Region</th>
<th scope="col">Compliance</th>
<th scope="col">Group</th>
<th scope="col">CheckID</th>
<th style="width:40%" scope="col">Check Title</th>

View File

@@ -108,6 +108,16 @@ bsd_get_iso8601_timestamp() {
"$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ"
}
gnu_convert_date_to_timestamp() {
date -d "$1" +%s
}
bsd_convert_date_to_timestamp() {
echo $(( $(date -j -f %Y-%m-%dT%H:%M:%S "$1" +%s) + 3600 ))
# Change above is because epoch time generator in BSD is 1h less than in Linux ¯\_(ツ)_/¯
#date -j -f "%Y-%m-%dT%H:%M:%S" "$1" "+%s"
}
gnu_test_tcp_connectivity() {
HOST=$1
PORT=$2
@@ -154,6 +164,9 @@ if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux-musl" ]; then
test_tcp_connectivity() {
gnu_test_tcp_connectivity "$1" "$2" "$3"
}
convert_date_to_timestamp() {
gnu_convert_date_to_timestamp "$1"
}
elif [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "freebsd"* ]]; then
# BSD/OSX commands compatibility
TEMP_REPORT_FILE=$(mktemp -t prowler.cred_report-XXXXXX)
@@ -189,6 +202,9 @@ elif [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "freebsd"* ]]; then
get_iso8601_timestamp() {
gnu_get_iso8601_timestamp
}
convert_date_to_timestamp() {
gnu_convert_date_to_timestamp "$1"
}
else
how_older_from_today() {
bsd_how_older_from_today "$1"
@@ -208,6 +224,9 @@ elif [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "freebsd"* ]]; then
get_iso8601_timestamp() {
bsd_get_iso8601_timestamp
}
convert_date_to_timestamp() {
bsd_convert_date_to_timestamp "$1"
}
fi
if "$BASE64_CMD" --version >/dev/null 2>&1 ; then
decode_report() {
@@ -248,6 +267,9 @@ elif [[ "$OSTYPE" == "cygwin" ]]; then
test_tcp_connectivity() {
gnu_test_tcp_connectivity "$1" "$2" "$3"
}
convert_date_to_timestamp() {
gnu_convert_date_to_timestamp "$1"
}
else
echo "Unknown Operating System! Valid \$OSTYPE: linux-gnu, linux-musl, darwin* or cygwin"
echo "Found: $OSTYPE"

View File

@@ -51,7 +51,7 @@ textPass(){
REPREGION=$REGION
fi
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}PASS${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1${SEP}$ASFF_COMPLIANCE_TYPE" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_CSV
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "Pass" | tee -a ${OUTPUT_FILE_NAME}.$EXTENSION_JSON
@@ -88,7 +88,7 @@ textInfo(){
REPREGION=$REGION
fi
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV}
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}INFO${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1${SEP}$ASFF_COMPLIANCE_TYPE" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV}
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "Info" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON}
@@ -140,7 +140,7 @@ textFail(){
fi
if [[ "${MODES[@]}" =~ "csv" ]]; then
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}${level}${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV}
echo "$PROFILE${SEP}$ACCOUNT_NUM${SEP}$REPREGION${SEP}$TITLE_ID${SEP}${level}${SEP}$ITEM_SCORED${SEP}$ITEM_LEVEL${SEP}$TITLE_TEXT${SEP}$1${SEP}$ASFF_COMPLIANCE_TYPE" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_CSV}
fi
if [[ "${MODES[@]}" =~ "json" ]]; then
generateJsonOutput "$1" "${level}" | tee -a ${OUTPUT_FILE_NAME}.${EXTENSION_JSON}
@@ -211,9 +211,9 @@ textTitle(){
:
else
if [[ "$ITEM_SCORED" == "Scored" ]]; then
echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT $group_ids"
echo -e "\n$BLUE $TITLE_ID $NORMAL $TITLE_TEXT $6 $group_ids "
else
echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $NORMAL $group_ids"
echo -e "\n$PURPLE $TITLE_ID $TITLE_TEXT $6 $NORMAL $group_ids "
fi
fi
}
@@ -232,6 +232,7 @@ generateJsonOutput(){
--arg ITEM_LEVEL "$ITEM_LEVEL" \
--arg TITLE_ID "$TITLE_ID" \
--arg REPREGION "$REPREGION" \
--arg TYPE "$ASFF_COMPLIANCE_TYPE" \
--arg TIMESTAMP "$(get_iso8601_timestamp)" \
-n '{
"Profile": $PROFILE,
@@ -245,6 +246,7 @@ generateJsonOutput(){
"Control ID": $TITLE_ID,
"Region": $REPREGION,
"Timestamp": $TIMESTAMP,
"Compliance": $TYPE
}'
}
@@ -266,7 +268,8 @@ generateJsonAsffOutput(){
--arg SEVERITY "$(echo $CHECK_SEVERITY| awk '{ print toupper($0) }')" \
--arg TITLE_ID "$TITLE_ID" \
--arg CHECK_ID "$CHECK_ID" \
--arg TYPE "$ASFF_TYPE" \
--arg TYPE "$ASFF_COMPLIANCE_TYPE" \
--arg COMPLIANCE_RELATED_REQUIREMENTS "$ASFF_COMPLIANCE_TYPE" \
--arg RESOURCE_TYPE "$ASFF_RESOURCE_TYPE" \
--arg REPREGION "$REPREGION" \
--arg TIMESTAMP "$(get_iso8601_timestamp)" \
@@ -303,7 +306,8 @@ generateJsonAsffOutput(){
}
],
"Compliance": {
"Status": $STATUS
"Status": $STATUS,
"RelatedRequirements": [ $COMPLIANCE_RELATED_REQUIREMENTS ]
}
}'
}
@@ -317,6 +321,7 @@ generateHtmlOutput(){
echo '<td>INFO</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ASFF_COMPLIANCE_TYPE'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
@@ -329,6 +334,7 @@ generateHtmlOutput(){
echo '<td>PASS</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ASFF_COMPLIANCE_TYPE'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
@@ -341,6 +347,7 @@ generateHtmlOutput(){
echo '<td>FAIL</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ASFF_COMPLIANCE_TYPE'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
@@ -353,6 +360,7 @@ generateHtmlOutput(){
echo '<td>WARN</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ACCOUNT_NUM'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$REPREGION'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ASFF_COMPLIANCE_TYPE'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$ITEM_LEVEL'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_ID'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML
echo '<td>'$TITLE_TEXT'</td>' >> ${OUTPUT_FILE_NAME}.$EXTENSION_HTML

View File

@@ -13,25 +13,47 @@
# Get whoami in AWS, who is the user running this shell script
GETCALLER=$($AWSCLI sts get-caller-identity $PROFILE_OPT --region $REGION)
ACCOUNT_NUM=$(echo $GETCALLER | jq -r '.Account')
# Get a list of all available AWS Regions
# sice describe-regions doesn't seem to work at me-south-1|eu-south-1|ap-east-1|af-south-1.
# Probably dased on https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
# when invoking regions with -r, those regions with STS disabled make GETCALLER fail then
# this if will filter them out (Africa (Cape Town), Asia Pacific (Hong Kong), Europe (Milan) and Middle East (Bahrain) ):
case "$REGION" in
me-south-1|eu-south-1|ap-east-1|af-south-1)
REGION_FOR_STS="us-east-1"
;;
*)
REGION_FOR_STS=$REGION
;;
esac
GETCALLER=$($AWSCLI sts get-caller-identity $PROFILE_OPT --region $REGION_FOR_STS)
RESULT_CALL=$?
if [[ $RESULT_CALL == 254 ]]; then
if [[ $PRINTCHECKSONLY || $PRINTGROUPSONLY ]]; then
echo Listing...
else
# Failed to get own identity ... exit
echo -e "$RED ERROR Getting credentials to run Prowler - EXITING! $NORMAL"
EXITCODE=2
exit $EXITCODE
fi
fi
if [[ $ACCOUNT_TO_ASSUME ]]; then
ACCOUNT_NUM=$ACCOUNT_TO_ASSUME
else
ACCOUNT_NUM=$(echo $GETCALLER | jq -r '.Account')
fi
CALLER_ARN=$(echo $GETCALLER | jq -r '.Arn')
USER_ID=$(echo $GETCALLER | jq -r '.UserId')
AWS_PARTITION=$(echo $CALLER_ARN| cut -d: -f2)
getWhoami(){
if [[ 255 -eq $? ]]; then
# Failed to get own identity ... exit
echo -e "$RED ERROR Getting credentials to run Prowler - EXITING! $NORMAL"
EXITCODE=2
exit $EXITCODE
fi
if [[ $ACCOUNT_TO_ASSUME ]]; then
ACCOUNT_NUM=$ACCOUNT_TO_ASSUME
fi
if [[ "$MODE" == "csv" ]]; then
if [[ 255 -eq $? ]]; then
# Failed to get own identity ... exit