#!/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. DATE_CMD="date" BASE64_CMD="base64" gnu_how_older_from_today() { DATE_TO_COMPARE=$1 TODAY_IN_DAYS=$("$DATE_CMD" -d "$("$DATE_CMD" +%Y-%m-%d)" +%s) DATE_FROM_IN_DAYS=$("$DATE_CMD" -d $DATE_TO_COMPARE +%s) DAYS_SINCE=$((($TODAY_IN_DAYS - $DATE_FROM_IN_DAYS )/60/60/24)) echo $DAYS_SINCE } bsd_how_older_from_today() { DATE_TO_COMPARE=$1 TODAY_IN_DAYS=$("$DATE_CMD" +%s) DATE_FROM_IN_DAYS=$("$DATE_CMD" -jf %Y-%m-%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 # output date format %Y-%m-%d gnu_timestamp_to_date() { # if date comes from cli v2 in format like 2020-04-29T10:13:09.191000-04:00 # we have to get only '%Y-%m-%d' if [[ $1 = 20* ]];then echo $1 | cut -f1 -d"T" else # remove fractions of a second TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".") OUTPUT_DATE=$("$DATE_CMD" -d @$TIMESTAMP_TO_CONVERT +'%Y-%m-%d') echo $OUTPUT_DATE fi } bsd_timestamp_to_date() { # if date comes from cli v2 in format like 2020-04-29T10:13:09.191000-04:00 # we have to get only '%Y-%m-%d' if [[ $1 = 20* ]];then echo $1 | cut -f1 -d"T" else # remove fractions of a second TIMESTAMP_TO_CONVERT=$(echo $1 | cut -f1 -d".") OUTPUT_DATE=$("$DATE_CMD" -r $TIMESTAMP_TO_CONVERT +'%Y-%m-%d') echo $OUTPUT_DATE fi } gnu_decode_report() { "$BASE64_CMD" -d } bsd_decode_report() { "$BASE64_CMD" -D } gnu_how_many_days_from_today() { DATE_TO_COMPARE=$1 TODAY_IN_DAYS=$("$DATE_CMD" -d "$("$DATE_CMD" +%Y-%m-%d)" +%s) DATE_IN_DAYS=$("$DATE_CMD" -d $DATE_TO_COMPARE +%s) DAYS_TO=$((( $DATE_IN_DAYS - $TODAY_IN_DAYS )/60/60/24)) echo $DAYS_TO } bsd_how_many_days_from_today() { DATE_TO_COMPARE=$1 TODAY_IN_DAYS=$("$DATE_CMD" +%s) DATE_IN_DAYS=$("$DATE_CMD" -jf %Y-%m-%d $DATE_TO_COMPARE +%s) DAYS_TO=$((( $DATE_IN_DAYS - $TODAY_IN_DAYS )/60/60/24)) echo $DAYS_TO } gnu_get_date_previous_than_months() { MONTHS_TO_COMPARE=$1 MONTHS_TO_COMPARE_IN_SECONDS=$(( 60 * 60 * 24 * 31 * $MONTHS_TO_COMPARE )) CURRENTSECS=$("$DATE_CMD" +%s) STARTDATEINSECS=$(( $CURRENTSECS - $MONTHS_TO_COMPARE_IN_SECONDS )) DATE_BEFORE_MONTHS_TO_COMPARE=$("$DATE_CMD" -d @$STARTDATEINSECS '+%Y-%m-%d') echo $DATE_BEFORE_MONTHS_TO_COMPARE } bsd_get_date_previous_than_months() { MONTHS_TO_COMPARE=$1 DATE_BEFORE_MONTHS_TO_COMPARE=$("$DATE_CMD" -v -$(echo $MONTHS_TO_COMPARE)m '+%Y-%m-%d') echo $DATE_BEFORE_MONTHS_TO_COMPARE } gnu_get_time_in_milliseconds() { "$DATE_CMD" +%s%3N } bsd_get_time_in_milliseconds() { # BSD date does not support outputting milliseconds, so pad with zeros "$DATE_CMD" +%s000 } gnu_get_iso8601_timestamp() { "$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ" } gsu_get_iso8601_hundred_days_ago() { "$DATE_CMD" -d "100 days ago" -u +"%Y-%m-%dT%H:%M:%SZ" } bsd_get_iso8601_timestamp() { "$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ" } bsd_get_iso8601_hundred_days_ago() { "$DATE_CMD" -v-100d -u +"%Y-%m-%dT%H:%M:%SZ" } gnu_test_tcp_connectivity() { HOST=$1 PORT=$2 TIMEOUT=$3 # This is initially for ES port 9300, not not HTTP but I add HTTP error # codes for better handling, so 200 is open and 000 is not responding timeout $TIMEOUT bash -c '(echo > /dev/tcp/'$HOST'/'$PORT') >/dev/null 2>&1 && echo "200" || echo "000"' } bsd_test_tcp_connectivity() { HOST=$1 PORT=$2 TIMEOUT=$3 # This is initially for ES port 9300, not not HTTP but I add HTTP error # codes for better handling, so 200 is open and 000 is not responding nc -z -G $TIMEOUT $HOST $PORT >/dev/null 2>&1 && echo "200" || echo "000" } # 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() { gnu_how_older_from_today "$1" } timestamp_to_date() { gnu_timestamp_to_date "$1" } decode_report() { gnu_decode_report } how_many_days_from_today() { gnu_how_many_days_from_today "$1" } get_date_previous_than_months() { gnu_get_date_previous_than_months "$1" } get_time_in_milliseconds() { gnu_get_time_in_milliseconds } get_iso8601_timestamp() { gnu_get_iso8601_timestamp } get_iso8601_hundred_days_ago() { gsu_get_iso8601_hundred_days_ago } test_tcp_connectivity() { gnu_test_tcp_connectivity "$1" "$2" "$3" } elif [[ "$OSTYPE" == "darwin"* ]]; then # BSD/OSX commands compatibility TEMP_REPORT_FILE=$(mktemp -t prowler.cred_report-XXXXXX) # It is possible that the user has installed GNU coreutils on OS X. By default, this will make GNU commands # available with a 'g' prefix, e.g. 'gdate'. Test if this is present, and use it if so, as it supports more features. # The user also may have replaced the default Mac OS X BSD tools with the GNU coreutils equivalents. # Only GNU date/base64 allows --version as a valid argument, so use the validity of this argument # as a means to detect that coreutils is installed and is overriding the default tools GDATE=$(which gdate) if [ -n "${GDATE}" ]; then DATE_CMD="gdate" fi GBASE64=$(which gbase64) if [ -n "${GBASE64}" ]; then BASE64_CMD="gbase64" fi if "$DATE_CMD" --version >/dev/null 2>&1 ; then how_older_from_today() { gnu_how_older_from_today "$1" } timestamp_to_date() { gnu_timestamp_to_date "$1" } how_many_days_from_today() { gnu_how_many_days_from_today "$1" } get_date_previous_than_months() { gnu_get_date_previous_than_months "$1" } get_time_in_milliseconds() { gnu_get_time_in_milliseconds } get_iso8601_timestamp() { gnu_get_iso8601_timestamp } else how_older_from_today() { bsd_how_older_from_today "$1" } timestamp_to_date() { bsd_timestamp_to_date "$1" } how_many_days_from_today() { bsd_how_many_days_from_today "$1" } get_date_previous_than_months() { bsd_get_date_previous_than_months "$1" } get_time_in_milliseconds() { bsd_get_time_in_milliseconds } get_iso8601_timestamp() { bsd_get_iso8601_timestamp } get_iso8601_hundred_days_ago() { bsd_get_iso8601_hundred_days_ago } fi if "$BASE64_CMD" --version >/dev/null 2>&1 ; then decode_report() { gnu_decode_report } else decode_report() { bsd_decode_report } fi test_tcp_connectivity() { bsd_test_tcp_connectivity "$1" "$2" "$3" } 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() { gnu_how_older_from_today "$1" } timestamp_to_date() { gnu_timestamp_to_date "$1" } decode_report() { gnu_decode_report } how_many_days_from_today() { gnu_how_many_days_from_today "$1" } get_date_previous_than_months() { gnu_get_date_previous_than_months "$1" } get_time_in_milliseconds() { gnu_get_time_in_milliseconds } get_iso8601_timestamp() { gnu_get_iso8601_timestamp } test_tcp_connectivity() { gnu_test_tcp_connectivity "$1" "$2" "$3" } else echo "Unknown Operating System! Valid \$OSTYPE: linux-gnu, linux-musl, darwin* or cygwin" echo "Found: $OSTYPE" EXITCODE=1 exit $EXITCODE fi