diff --git a/README.md b/README.md index ac703a8137..bc1a3fa1a1 100644 --- a/README.md +++ b/README.md @@ -434,6 +434,10 @@ In order to add any new check feel free to create a new extra check in the extra ## Third Party Integrations +### AWS Security Hub + +There is a blog post about that integration in the AWS Security blog here + ### Telegram Javier Pecete has done an awesome job integrating Prowler with Telegram, you have more details here diff --git a/checks/check11 b/checks/check11 index 1150ac8b94..924a14eb91 100644 --- a/checks/check11 +++ b/checks/check11 @@ -19,11 +19,17 @@ check11(){ MAX_DAYS=-1 last_login_date=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$5 }' |grep '' | awk '{ print $2 }') arn=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$2 }' |grep '' | awk '{ print $2 }') - days_not_in_use=$(how_many_days_from_today ${last_login_date%T*}) - if [ "$days_not_in_use" -gt "$MAX_DAYS" ];then - textFail "Root Account $arn last accessed was less then ${MAX_DAYS#-} day ago" + #check if last_login_date date is a valid date, if not, its a pass. + if [[ ${last_login_date%T*} =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]];then + days_not_in_use=$(how_many_days_from_today ${last_login_date%T*}) + if [ "$days_not_in_use" -gt "$MAX_DAYS" ];then + textFail "Root Account $arn last accessed was less then ${MAX_DAYS#-} day ago" + else + textPass "Root Account $arn last accessed was more then ${MAX_DAYS#-} day ago" + fi else - textPass "Root Account $arn last accessed was more then ${MAX_DAYS#-} day ago" + textPass "Root Account $arn last accessed was more then ${MAX_DAYS#-} day ago" fi + } diff --git a/checks/check119 b/checks/check119 index 5555bbe785..015836e392 100644 --- a/checks/check119 +++ b/checks/check119 @@ -15,7 +15,21 @@ CHECK_TYPE_check119="LEVEL2" CHECK_ALTERNATE_check119="check119" check119(){ - # "Ensure IAM instance roles are used for AWS resource access from instances (Not Scored)" - textInfo "No command available for check 1.19 " - textInfo "See section 1.19 on the CIS Benchmark guide for details " + for regx in $REGIONS; do + EC2_DATA=$($AWSCLI ec2 describe-instances $PROFILE_OPT --region $regx --query 'Reservations[].Instances[].[InstanceId, IamInstanceProfile.Arn]') + EC2_DATA=$(echo $EC2_DATA | jq '.[]|{InstanceId: .[0], ProfileArn: .[1]}') + INSTANCE_LIST=$(echo $EC2_DATA | jq -r '.InstanceId') + if [[ $INSTANCE_LIST ]]; then + for instance in $INSTANCE_LIST; do + PROFILEARN=$(echo $EC2_DATA | jq -r --arg i "$instance" 'select(.InstanceId==$i)|.ProfileArn') + if [[ $PROFILEARN == "null" ]]; then + textFail "$regx: Instance $instance not associated with an instance role." $regx + else + textPass "$regx: Instance $instance associated with role ${PROFILEARN##*/}." $regx + fi + done + else + textInfo "$regx: No EC2 instances found" $regx + fi + done } diff --git a/checks/check29 b/checks/check29 index c92542b0d5..d1f23dc8c1 100644 --- a/checks/check29 +++ b/checks/check29 @@ -19,13 +19,13 @@ check29(){ for regx in $REGIONS; do AVAILABLE_VPC=$($AWSCLI ec2 describe-vpcs $PROFILE_OPT --region $regx --query 'Vpcs[?State==`available`].VpcId' --output text) for vpcx in $AVAILABLE_VPC; do - CHECK_FL=$($AWSCLI ec2 describe-flow-logs $PROFILE_OPT --region $regx --query 'FlowLogs[?FlowLogStatus==`ACTIVE`||ResourceId==`${vpcx}`].FlowLogId' --output text) + CHECK_FL=$($AWSCLI ec2 describe-flow-logs $PROFILE_OPT --region $regx --filter Name="resource-id",Values="${vpcx}" --query 'FlowLogs[?FlowLogStatus==`ACTIVE`].FlowLogId' --output text) if [[ $CHECK_FL ]];then for FL in $CHECK_FL;do - textPass "VPCFlowLog is enabled for LogGroupName: $FL in Region $regx" "$regx" + textPass "VPC $vpcx: VPCFlowLog is enabled for LogGroupName: $FL in Region $regx" "$regx" done else - textFail "No VPCFlowLog has been found in Region $regx" "$regx" + textFail "VPC $vpcx: No VPCFlowLog has been found in Region $regx" "$regx" fi done done diff --git a/checks/check_extra774 b/checks/check_extra774 new file mode 100644 index 0000000000..baae7869a9 --- /dev/null +++ b/checks/check_extra774 @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +CHECK_ID_extra774="1.23" +CHECK_TITLE_extra774="[extra774] Check if user have unused console login" +CHECK_SCORED_extra774="NOT_SCORED" +CHECK_TYPE_extra774="EXTRA" +CHECK_ALTERNATE_check774="extra774" + +extra774(){ + MAX_DAYS=-30 + LIST_USERS_WITH_PASSWORD_ENABLED=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$4,$5 }' |grep true | awk '{ print $1 }') + + for i in $LIST_USERS_WITH_PASSWORD_ENABLED; do + user=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$3 }' |grep "^$i " |awk '{ print $1 }') + last_login_date=$(cat $TEMP_REPORT_FILE|awk -F, '{ print $1,$3 }' |grep "^$i " |awk '{ print $2 }') + + days_not_in_use=$(how_many_days_from_today ${last_login_date%T*}) + if [ "$days_not_in_use" -lt "$MAX_DAYS" ];then + textFail "User $user has not used console login for more then ${MAX_DAYS#-} days" + else + textPass "User $user has used console login in the past ${MAX_DAYS#-} days" + fi + done +} diff --git a/iam/prowler-additions-policy.json b/iam/prowler-additions-policy.json index ccb178dd3a..213c811ea0 100644 --- a/iam/prowler-additions-policy.json +++ b/iam/prowler-additions-policy.json @@ -92,7 +92,6 @@ "secretsmanager:listsecretversionids", "servicecatalog:list*", "ses:list*", - "ses:sendemail", "sns:list*", "sqs:listqueuetags", "ssm:listassociations", diff --git a/prowler b/prowler index e4e096d000..7a2c80b3d5 100755 --- a/prowler +++ b/prowler @@ -247,7 +247,7 @@ execute_check() { # Generate the credential report, only if it is group1 related which checks we # run so that the checks can safely assume it's available if [ ${alternate_name} ];then - if [[ ${alternate_name} == check1* ]];then + if [[ ${alternate_name} == check1* || ${alternate_name} == extra71 ]];then if [ ! -s $TEMP_REPORT_FILE ];then genCredReport saveReport @@ -260,7 +260,7 @@ execute_check() { local check_id_var=CHECK_ID_$1 local check_id=${!check_id_var} if [ ${check_id} ]; then - if [[ ${check_id} == 1* ]];then + if [[ ${check_id} == 1* || ${check_id} == 7.1,7.01 ]];then if [ ! -s $TEMP_REPORT_FILE ];then genCredReport saveReport