#!/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, which is ISO8601 # remove fractions of a second TIMESTAMP_TO_CONVERT=$(cut -f1 -d"." <<< "${1}") if ! "${DATE_CMD}" -d "${TIMESTAMP_TO_CONVERT}" +%s > /dev/null 2>&1; then # If input is epoch use the @ OUTPUT_DATE=$("${DATE_CMD}" -d @"${TIMESTAMP_TO_CONVERT}" +'%Y-%m-%d') else # If input is not epoch dont use @ OUTPUT_DATE=$("${DATE_CMD}" -d "${TIMESTAMP_TO_CONVERT}" +'%Y-%m-%d') fi echo "${OUTPUT_DATE}" } bsd_timestamp_to_date() { # if date comes from cli v2 in format like 2020-04-29T10:13:09.191000-04:00, which is ISO8601 # remove fractions of a second TIMESTAMP_TO_CONVERT=$(cut -f1 -d"." <<< "${1}") OUTPUT_DATE=$("${DATE_CMD}" -jf %Y-%m-%d "${TIMESTAMP_TO_CONVERT}" +%F 2>/dev/null) echo "${OUTPUT_DATE}" } 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" } bsd_get_iso8601_timestamp() { "$DATE_CMD" -u +"%Y-%m-%dT%H:%M:%SZ" } gnu_convert_date_to_timestamp() { # if [ "$OSTYPE" == "linux-musl" ]; then # date -D "%Y-%m-%dT%H:%M:%SZ" -d "$1" +%s # else date -u -d "$1" +%s # fi } bsd_convert_date_to_timestamp() { echo $(date -u -j -f %Y-%m-%dT%H:%M:%S "$1" +%s) #date -j -f "%Y-%m-%dT%H:%M:%S" "$1" "+%s" } 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" } gnu_replace_sed(){ sed -i $1 $2 } bsd_replace_sed(){ sed -i '' $1 $2 } # 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 } test_tcp_connectivity() { gnu_test_tcp_connectivity "$1" "$2" "$3" } convert_date_to_timestamp() { gnu_convert_date_to_timestamp "$1" } replace_sed() { gnu_replace_sed $1 $2 } elif [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "freebsd"* ]]; 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 } convert_date_to_timestamp() { gnu_convert_date_to_timestamp "$1" } 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 } convert_date_to_timestamp() { bsd_convert_date_to_timestamp "$1" } 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" } replace_sed() { bsd_replace_sed $1 $2 } 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" } convert_date_to_timestamp() { gnu_convert_date_to_timestamp "$1" } replace_sed() { gnu_replace_sed $1 $2 } else echo "Unknown Operating System! Valid \$OSTYPE: linux-gnu, linux-musl, darwin* or cygwin" echo "Found: $OSTYPE" EXITCODE=1 exit $EXITCODE fi