From 2f9b793b785c868388cf71c59cfccb42cffa7f58 Mon Sep 17 00:00:00 2001 From: mboelen Date: Wed, 21 Oct 2015 23:26:41 +0200 Subject: Added logging of maximum password retries --- plugins/plugin_pam_phase1 | 393 +--------------------------------------------- 1 file changed, 1 insertion(+), 392 deletions(-) (limited to 'plugins') diff --git a/plugins/plugin_pam_phase1 b/plugins/plugin_pam_phase1 index 06370b5d..57ca365d 100644 --- a/plugins/plugin_pam_phase1 +++ b/plugins/plugin_pam_phase1 @@ -6,7 +6,7 @@ #----------------------------------------------------- # PLUGIN_AUTHOR=Michael Boelen # PLUGIN_CATEGORY=authentication -# PLUGIN_DATE=2015-10-01 +# PLUGIN_DATE=2015-10-21 # PLUGIN_DESC=PAM # PLUGIN_NAME=pam # PLUGIN_PACKAGE=all @@ -376,384 +376,6 @@ if [ ${PAM_PASSWORD_STRENGTH_TESTED} -eq 1 ]; then fi fi -#!/bin/sh - -######################################################################### -# -# * DO NOT REMOVE * -#----------------------------------------------------- -# PLUGIN_AUTHOR=Michael Boelen -# PLUGIN_CATEGORY=authentication -# PLUGIN_DATE=2015-10-01 -# PLUGIN_DESC=PAM -# PLUGIN_NAME=pam -# PLUGIN_PACKAGE=all -# PLUGIN_REQUIRED_TESTS= -# PLUGIN_VERSION=1.0.0 -#----------------------------------------------------- -######################################################################### -# - PAM_DIRECTORY="/etc/pam.d" - # Test : PLGN-0010 - # Description : Check PAM configuration - if [ -f /etc/pam.conf -o -d /etc/pam.d ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi - Register --test-no PLGN-0010 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check PAM configuration" --progress - if [ ${SKIPTEST} -eq 0 ]; then - FOUNDPROBLEM=0 - # Check if the PAM directory structure exists - if [ -d ${PAM_DIRECTORY} ]; then - logtext "Result: /etc/pam.d exists" - FIND_FILES=`find ${PAM_DIRECTORY} -type f -print` - # First check /etc/pam.conf if it exists. - #if [ -f /etc/pam.conf ]; then FIND="/etc/pam.conf ${FIND}"; fi - for PAM_FILE in ${FIND_FILES}; do - #echo "" - logtext "Now checking PAM file ${PAM_FILE}" - while read line; do - # Strip empty lines, commented lines, tabs, line breaks (\), then finally remove all double spaces - LINE=`echo $line | grep -v "^#" | grep -v "^$" | tr '\011' ' ' | sed 's/\\\n/ /' | sed 's/ / /g' | sed 's/ #\(.*\)$//'` - if [ ! "${LINE}" = "" ]; then - PAM_SERVICE=`echo ${PAM_FILE} | awk -F/ '{ print $NF }'` - PAM_CONTROL_FLAG="-" - PAM_CONTROL_OPTIONS="-" - PAM_MODULE="-" - PAM_MODULE_OPTIONS="-" - PAM_TYPE=`echo ${LINE} | awk '{ print $1 }'` - PARSELINE=0 - case ${PAM_TYPE} in - "@include") - FILE=`echo ${LINE} | awk '{ print $2 }'` - logtext "Result: Found @include. Does include PAM settings from file ${FILE} (which is individually processed)" - ;; - "account") - PARSELINE=1 - ;; - "auth") - PARSELINE=1 - ;; - "password") - PARSELINE=1 - ;; - "session") - PARSELINE=1 - ;; - *) - logtext "Exception: Unknown PAM type found" - ;; - esac - if [ ${PARSELINE} -eq 1 ]; then - MULTIPLE_OPTIONS=`echo ${LINE} | awk '$2 ~ /^\[/'` - if [ ! "${MULTIPLE_OPTIONS}" = "" ]; then - # Needs more parsing, depending on the options found - PAM_CONTROL_OPTIONS=`echo ${LINE} | sed "s/^.*\[//" | sed "s/\].*$//"` - logtext "Result: Found brackets in line, indicating multiple options for control flags: ${PAM_CONTROL_OPTIONS}" - LINE=`echo ${LINE} | sed "s/ \[.*\] / other /"` - fi - PAM_MODULE=`echo ${LINE} | awk '{ print $3 }'` - PAM_MODULE_OPTIONS=`echo ${LINE} | cut -d ' ' -f 4-` - PAM_CONTROL_FLAG=`echo ${LINE} | awk '{ print $2 }'` - case ${PAM_CONTROL_FLAG} in - "optional"|"required"|"requisite"|"sufficient") - Debug "Found a common control flag: ${PAM_CONTROL_FLAG} for ${PAM_MODULE}" - ;; - "other") - logtext "Result: brackets used, ignoring control flags" - ;; - *) - logtext "Unknown control flag found (${PAM_CONTROL_FLAG})" - ;; - esac - if [ ! "${PAM_MODULE_OPTIONS}" = "" ]; then - logtext "Result: using module ${PAM_MODULE} (${PAM_CONTROL_FLAG}) with options ${PAM_MODULE_OPTIONS}" - else - PAM_MODULE_OPTIONS="-" - logtext "Result: using module ${PAM_MODULE} (${PAM_CONTROL_FLAG}) without options configured" - fi - - PAM_MODULE_NAME=`echo ${PAM_MODULE} | sed 's/.so$//'` - # - # Specific PAMs are commonly seen on these platforms: - # - # FreeBSD Linux - # pam_access v - # pam_deny v v - # pam_group v - # pam_krb5 v - # pam_lastlog v - # pam_login_access v - # pam_nologin v - # pam_opie v - # pam_opieaccess v - # pam_passwdqc v - # pam_permit v - # pam_rhosts v - # pam_rootok v - # pam_securetty v - # pam_self v - # pam_ssh v - # pam_unix v - - case ${PAM_MODULE_NAME} in - pam_access) ;; - pam_cap) ;; - pam_debug | pam_deny) ;; - pam_echo| pam_env | pam_exec | pam_faildelay) ;; - pam_filter | pam_ftp) ;; - # Google Authenticator / YubiKey - # Common to find it only enabled for SSH - pam_google_authenticator | pam_yubico) - logtext "Result: found pam_google_authenticator" - if [ "${PAM_CONTROL_FLAG}" = "required" ]; then - PAM_2F_AUTH_ENABLED=1 - PAM_2F_AUTH_REQUIRED=1 - report "authentication_2f_provider[]=${PAM_MODULE_NAME}" - report "authentication_2f_service[]=${PAM_SERVICE}" - elif -o "${PAM_CONTROL_FLAG}" = "sufficient" ]; then - PAM_2F_AUTH_ENABLED=1 - report "authentication_2f_provider[]=${PAM_MODULE_NAME}" - report "authentication_2f_service[]=${PAM_SERVICE}" - else - logtext "exception: found 2F authenticator enabled with uncommon control flag: ${PAM_CONTROL_FLAG}" - fi - ;; - pam_group) ;; - pam_issue) ;; - pam_keyinit | pam_krb5) ;; - pam_lastlog | pam_limits) ;; - # Log UID for auditd - pam_loginuid) - PAM_LOGINUID_FOUND=1 - ;; - pam_listfile | pam_localuser) ;; - pam_mail | pam_mkhomedir | pam_motd) ;; - pam_namespace | pam_nologin) ;; - pam_permit) ;; - pam_rootok) ;; - pam_rhosts) ;; - pam_securetty) ;; - pam_self) ;; - pam_shells) ;; - pam_stress | pam_succeed_if | pam_systemd) ;; - pam_time | pam_timestamp) ;; - pam_umask) ;; - # Password history - # Can be configured via pam_unix or pam_pwhistory - pam_unix | pam_pwhistory) - logtext "Result: found ${PAM_MODULE} module (generic)" - if [ ! "${PAM_MODULE_OPTIONS}" = "" ]; then - for I in ${PAM_MODULE_OPTIONS}; do - OPTION=`echo ${I} | awk -F= '{ print $1 }'` - VALUE=`echo ${I} | awk -F= '{ print $2 }'` - CREDITS_CONFIGURED=0 - case ${OPTION} in - # pam_pwhistory / pam_unix - remember) - # Minimum length (remove 1 if credits are configured, at later stage in function) - logtext "Result: password history configured" - DigitsOnly ${VALUE} - PAM_PASSWORD_HISTORY_AMOUNT=${VALUE} - PAM_PASSWORD_HISTORY_ENABLED=1 - Debug "Found password history enabled with module ${PAM_MODULE_NAME} and password amount ${PAM_PASSWORD_HISTORY_AMOUNT}" - ;; - esac - done - fi - ;; - pam_unix_acct| pam_unix_auth | pam_unix_passwd | pam_unix_session | pam_unix2) ;; - pam_vbox) ;; - pam_warn | pam_wheel) ;; - pam_xauth) ;; - - # Password strength testing - pam_cracklib | pam_pwquality) - logtext "Result: found module ${PAM_MODULE} for password strength testing" - - # Set default values - if [ "${CREDITS_D_PASSWORD}" = "" ]; then CREDITS_D_PASSWORD=1; fi - if [ "${CREDITS_L_PASSWORD}" = "" ]; then CREDITS_L_PASSWORD=1; fi - if [ "${CREDITS_O_PASSWORD}" = "" ]; then CREDITS_O_PASSWORD=1; fi - if [ "${CREDITS_U_PASSWORD}" = "" ]; then CREDITS_U_PASSWORD=1; fi - if [ "${MAX_PASSWORD_RETRY}" = "" ]; then MAX_PASSWORD_RETRY=1; fi - if [ "${MIN_PASSWORD_CLASS}" = "" ]; then MIN_PASSWORD_CLASS=0; fi - if [ "${MIN_PASSWORD_LENGTH}" = "" ]; then MIN_PASSWORD_LENGTH=6; fi - - PAM_PASSWORD_STRENGTH_TESTED=1 - if [ ! "${PAM_MODULE_OPTIONS}" = "" ]; then - Debug "Module options configured" - for I in ${PAM_MODULE_OPTIONS}; do - OPTION=`echo ${I} | awk -F= '{ print $1 }'` - Debug ${OPTION} - VALUE=`echo ${I} | awk -F= '{ print $2 }'` - CREDITS_CONFIGURED=0 - case ${OPTION} in - minlen) - # Minimum length (remove 1 if credits are configured, at later stage in function) - logtext "Result: minlen configured" - DigitsOnly ${VALUE} - MIN_PASSWORD_LENGTH=${VALUE} - ;; - retry) - # Maximum password retry - logtext "Result: Max password Retry configured" - DigitsOnly ${VALUE} - MAX_PASSWORD_RETRY=${VALUE} - ;; - minclass) - # Minimum number of class required out of upper, lower, digit and oters - logtext "Result: Min number of password class is configured" - MIN_PASSWORD_CLASS=${VALUE} - ;; - dcredit) - CREDITS_D_PASSWORD=${VALUE} - ;; - lcredit) - CREDITS_L_PASSWORD=${VALUE} - ;; - ocredit) - CREDITS_O_PASSWORD=${VALUE} - ;; - ucredit) - CREDITS_U_PASSWORD=${VALUE} - ;; - *) - logtext "Result: unknown option found: ${OPTION} with value ${VALUE}" - ;; - esac - done - fi - ;; - - pam_tally | pam_tally2) - if [ "${PAM_CONTROL_FLAG}" = "required" ]; then - logtext "Result: found a required module for countering brute force cracking attempts" - report "pam_auth_brute_force_protection_module[]=${PAM_MODULE_NAME}" - PAM_AUTH_BRUTE_FORCE_PROTECTION=1 - fi - if [ ! "${PAM_MODULE_OPTIONS}" = "" ]; then - for I in ${PAM_MODULE_OPTIONS}; do - OPTION=`echo ${I} | awk -F= '{ print $1 }'` - VALUE=`echo ${I} | awk -F= '{ print $2 }'` - case ${OPTION} in - deny) - AUTH_BLOCK_BAD_LOGIN_ATTEMPTS="${VALUE}" - ;; - unlock_time) - AUTH_UNLOCK_TIME="${VALUE}" - ;; - esac - done - fi - ;; - "-") - logtext "NOTE: this module is not parsed, as it uses an unknown control flag or type" - ;; - *) - logtext "Result: found pluggable authentication module ${PAM_MODULE}, which is unknown" - ;; - esac - fi - #Debug "Service: ${PAM_SERVICE}" - #Debug "Type: ${PAM_TYPE}" - #Debug "Control: ${PAM_CONTROL_FLAG}" - #Debug "Control options: ${PAM_CONTROL_OPTIONS}" - #Debug "Module: ${PAM_MODULE_NAME}" - #Debug "Module options: ${PAM_MODULE_OPTIONS}" - fi - done < ${PAM_FILE} - #ParsePAMLine ${J} - #StoreSetting "pam" " - done - fi - fi -# -################################################################################# -# - -# /etc/security/opasswd should exist when: -# password history is enabled via pam_unix -# pam_cracklib or pam_pwquality is used -# In that case, the file should be owned by root, with 440/640/660 permissions - -logtext "[PAM] PAM 2F authentication enabled: ${PAM_2F_AUTH_ENABLED}" -report "authentication_two_factor_enabled=${PAM_2F_AUTH_ENABLED}" - -logtext "[PAM] PAM 2F authentication required: ${PAM_2F_AUTH_REQUIRED}" -report "authentication_two_factor_required=${PAM_2F_AUTH_ENABLED}" - -if [ ! "${AUTH_UNLOCK_TIME}" = "-1" ]; then - logtext "[PAM] Authentication unlock time: ${AUTH_UNLOCK_TIME}" - report "authentication_unlock_time=${AUTH_UNLOCK_TIME}" - else - logtext "[PAM] Authentication unlock time: not configured" -fi - -logtext "[PAM] Password brute force protection: ${PAM_AUTH_BRUTE_FORCE_PROTECTION}" - -if [ ${PAM_AUTH_BRUTE_FORCE_PROTECTION} -eq 1 ]; then - report "authentication_brute_force_protection=1" -fi - -if [ ! "${MIN_PASSWORD_LENGTH}" = "-1" ]; then - logtext "[PAM] Minimum password length: ${MIN_PASSWORD_LENGTH}" - report "minimum_password_length=${MIN_PASSWORD_LENGTH}" - else - logtext "[PAM] Minimum password length: not configured" -fi - -logtext "[PAM] Password strength testing enabled: ${PAM_PASSWORD_STRENGTH_TESTED}" -if [ ${PAM_PASSWORD_STRENGTH_TESTED} -eq 1 ]; then - report "password_strength_tested=1" - - if [ ${CREDITS_D_PASSWORD} -ge 1 ] && [ ${CREDITS_L_PASSWORD} -ge 1 ] && [ ${CREDITS_O_PASSWORD} -ge 1 ] && [ ${CREDITS_U_PASSWORD} -ge 1 ]; then - # Show how many password class are required out of 4 - logtext "[PAM] Minimum password class out of 4: ${MIN_PASSWORD_CLASS}" - report "min_password_class=${MIN_PASSWORD_CLASS}" - else - logtext "[PAM] Minimum password class setting of ${MIN_PASSWORD_CLASS} out of 4 is ignored since at least 1 class are forced " - report "min_password_class=ignored" - fi - - # Digits - if [ ${CREDITS_D_PASSWORD} -lt 0 ]; then - CREDITS_D_PASSWORD=`echo ${CREDITS_D_PASSWORD} | cut -b 2-` - logtext "[PAM] Minimum number of Digital characters required: ${CREDITS_D_PASSWORD}" - report "password_min_digital_required=${CREDITS_D_PASSWORD}" - elif [ ${CREDITS_D_PASSWORD} -ge 0 ]; then - logtext "[PAM] Maximum credit for Digital characters: ${CREDITS_D_PASSWORD}" - report "password_max_digital_credit=${CREDITS_D_PASSWORD}" - fi - - # Lowercase - if [ ${CREDITS_L_PASSWORD} -lt 0 ]; then - CREDITS_L_PASSWORD=`echo ${CREDITS_L_PASSWORD} | cut -b 2-` - logtext "[PAM] Minimum number of Lowercase characters required: ${CREDITS_L_PASSWORD}" - report "password_min_l_required=${CREDITS_L_PASSWORD}" - elif [ ${CREDITS_L_PASSWORD} -ge 0 ]; then - logtext "[PAM] Maximum credit for Lowercase characters: ${CREDITS_L_PASSWORD}" - report "password_max_l_credit=${CREDITS_L_PASSWORD}" - fi - - # Other characters - if [ ${CREDITS_O_PASSWORD} -lt 0 ]; then - CREDITS_O_PASSWORD=`echo ${CREDITS_O_PASSWORD} | cut -b 2-` - logtext "[PAM] Minimum number of Other characters required: ${CREDITS_O_PASSWORD}" - report "password_min_other_required=${CREDITS_O_PASSWORD}" - elif [ ${CREDITS_O_PASSWORD} -ge 0 ]; then - logtext "[PAM] Maximum credit for Other characters: ${CREDITS_O_PASSWORD}" - report "password_max_other_credit=${CREDITS_O_PASSWORD}" - fi - - # Uppercase - if [ ${CREDITS_U_PASSWORD} -lt 0 ]; then - CREDITS_U_PASSWORD=`echo ${CREDITS_U_PASSWORD} | cut -b 2-` - logtext "[PAM] Minimum number of Uppercase characters required: ${CREDITS_U_PASSWORD}" - report "password_min_u_required=${CREDITS_U_PASSWORD}" - elif [ ${CREDITS_U_PASSWORD} -ge 0 ]; then - logtext "[PAM] Maximum credit for Uppercase characters: ${CREDITS_U_PASSWORD}" - report "password_max_u_credit=${CREDITS_U_PASSWORD}" - fi -fi - # Show how many retries are allowed to change password logtext "[PAM] Password maximum retry: ${MAX_PASSWORD_RETRY}" report "max_password_retry=${MAX_PASSWORD_RETRY}" @@ -769,17 +391,4 @@ logtext "[PAM] Password history enabled: ${PAM_PASSWORD_HISTORY_ENABLED}" logtext "[PAM] Password history amount: ${PAM_PASSWORD_HISTORY_AMOUNT}" -#EOF - -# If auditd is running, but pam_loginuid not, events might not be properly logged -if [ ${AUDITD_RUNNING} -eq 1 ]; then - if [ ${PAM_LOGINUID_FOUND} -eq 0 ]; then - report "pam_issue[]=pam_loginuid is missing" - fi -fi - -logtext "[PAM] Password history enabled: ${PAM_PASSWORD_HISTORY_ENABLED}" -logtext "[PAM] Password history amount: ${PAM_PASSWORD_HISTORY_AMOUNT}" - - #EOF -- cgit v1.2.3