From 6bc427a916b95453bbd4f7d00ea7c35e36295200 Mon Sep 17 00:00:00 2001 From: Stephane Lesimple Date: Tue, 21 Nov 2023 11:18:55 +0100 Subject: [PATCH] Adapt 5.3.4, 99.5.4.5.1 and 99.5.4.5.2 to yescrypt --- bin/hardening/5.3.4_acc_pam_sha512.sh | 21 +++++++++--- .../99.5.4.5.1_acc_logindefs_sha512.sh | 32 ++++++++++++++----- bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh | 18 ++++++++--- tests/hardening/5.3.4_acc_pam_sha512.sh | 2 +- .../99.5.4.5.1_acc_logindefs_sha512.sh | 6 ++-- .../hardening/99.5.4.5.2_acc_shadow_sha512.sh | 6 ++-- tests/launch_tests.sh | 5 +++ 7 files changed, 65 insertions(+), 25 deletions(-) diff --git a/bin/hardening/5.3.4_acc_pam_sha512.sh b/bin/hardening/5.3.4_acc_pam_sha512.sh index 0cb60451..bdd84a0f 100755 --- a/bin/hardening/5.3.4_acc_pam_sha512.sh +++ b/bin/hardening/5.3.4_acc_pam_sha512.sh @@ -15,20 +15,18 @@ set -u # One variable unset, it's over # shellcheck disable=2034 HARDENING_LEVEL=2 # shellcheck disable=2034 -DESCRIPTION="Check that any password that may exist in /etc/shadow is yescrypt (or SHA512 for debian 10) hashed and salted" +DESCRIPTION="Check that the algorithm declared in PAM for password changes is sha512 (or yescrypt for Debian 11+)" CONF_FILE="/etc/pam.d/common-password" -CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*sha512" +# CONF_LINE is defined in _set_vars_jit below # This function will be called if the script status is on enabled / audit mode audit() { + _set_vars_jit # Check conf file for default SHA512 hash if $SUDO_CMD [ ! -r "$CONF_FILE" ]; then crit "$CONF_FILE is not readable" else - if [ "$DEB_MAJ_VER" -ge "11" ]; then - CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*yescrypt" # https://github.com/ovh/debian-cis/issues/158 - fi # shellcheck disable=SC2001 does_pattern_exist_in_file "$CONF_FILE" "$(sed 's/ /[[:space:]]+/g' <<<"$CONF_LINE")" if [ "$FNRET" = 0 ]; then @@ -41,6 +39,7 @@ audit() { # This function will be called if the script status is on enabled mode apply() { + _set_vars_jit if $SUDO_CMD [ ! -r "$CONF_FILE" ]; then crit "$CONF_FILE is not readable" else @@ -64,6 +63,18 @@ check_config() { : } +# As we use DEB_MAJ_VER, which is set by constants.sh, itself sourced by main.sh below, +# We need to call this in the subs called by main.sh when it is sourced, otherwise it would +# either be too soon (DEB_MAJ_VER not defined) or too late (test has already been run) +_set_vars_jit() { + if [ "$DEB_MAJ_VER" -ge "11" ]; then + CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*(sha512|yescrypt)" # https://github.com/ovh/debian-cis/issues/158 + else + CONF_LINE="^\s*password\s.+\s+pam_unix\.so\s+.*sha512" + fi + unset -f _set_vars_jit +} + # Source Root Dir Parameter if [ -r /etc/default/cis-hardening ]; then # shellcheck source=../../debian/default diff --git a/bin/hardening/99.5.4.5.1_acc_logindefs_sha512.sh b/bin/hardening/99.5.4.5.1_acc_logindefs_sha512.sh index 5bfcd6af..cd7ae5c1 100755 --- a/bin/hardening/99.5.4.5.1_acc_logindefs_sha512.sh +++ b/bin/hardening/99.5.4.5.1_acc_logindefs_sha512.sh @@ -6,7 +6,7 @@ # # -# 99.5.4.5.1 Check that any password that will be created will be SHA512 hashed and salted +# 99.5.4.5.1 Check that any password that will be created will use sha512crypt (or yescrypt for Debian 11+) # set -e # One error, it's over @@ -15,31 +15,33 @@ set -u # One variable unset, it's over # shellcheck disable=2034 HARDENING_LEVEL=2 # shellcheck disable=2034 -DESCRIPTION="Check that any password that will be created will be SHA512 hashed and salted" +DESCRIPTION="Check that any password that will be created will use sha512crypt (or yescrypt for Debian 11+)" CONF_FILE="/etc/login.defs" -CONF_LINE="ENCRYPT_METHOD SHA512" +# CONF_LINE and CONF_LINE_REGEX are defined in _set_vars_jit below # This function will be called if the script status is on enabled / audit mode audit() { + _set_vars_jit # Check conf file for default SHA512 hash if $SUDO_CMD [ ! -r "$CONF_FILE" ]; then crit "$CONF_FILE is not readable" else - does_pattern_exist_in_file "$CONF_FILE" "^ *${CONF_LINE/ /[[:space:]]+}" + does_pattern_exist_in_file "$CONF_FILE" "^ *${CONF_LINE_REGEX/ /[[:space:]]+}" if [ "$FNRET" = 0 ]; then - ok "$CONF_LINE is present in $CONF_FILE" + ok "$CONF_LINE_REGEX is present in $CONF_FILE" else - crit "$CONF_LINE is not present in $CONF_FILE" + crit "$CONF_LINE_REGEX is not present in $CONF_FILE" fi fi } # This function will be called if the script status is on enabled mode apply() { - does_pattern_exist_in_file "$CONF_FILE" "^ *${CONF_LINE/ /[[:space:]]+}" + _set_vars_jit + does_pattern_exist_in_file "$CONF_FILE" "^ *${CONF_LINE_REGEX/ /[[:space:]]+}" if [ "$FNRET" = 0 ]; then - ok "$CONF_LINE is present in $CONF_FILE" + ok "$CONF_LINE_REGEX is present in $CONF_FILE" else warn "$CONF_LINE is not present in $CONF_FILE, adding it" does_pattern_exist_in_file "$CONF_FILE" "^$(echo "$CONF_LINE" | cut -d ' ' -f1)" @@ -57,6 +59,20 @@ check_config() { : } +# As we use DEB_MAJ_VER, which is set by constants.sh, itself sourced by main.sh below, +# We need to call this in the subs called by main.sh when it is sourced, otherwise it would +# either be too soon (DEB_MAJ_VER not defined) or too late (test has already been run) +_set_vars_jit() { + if [ "$DEB_MAJ_VER" -ge "11" ]; then + CONF_LINE_REGEX="ENCRYPT_METHOD (SHA512|yescrypt|YESCRYPT)" + CONF_LINE="ENCRYPT_METHOD YESCRYPT" + else + CONF_LINE_REGEX="ENCRYPT_METHOD SHA512" + CONF_LINE="ENCRYPT_METHOD SHA512" + fi + unset -f _set_vars_jit +} + # Source Root Dir Parameter if [ -r /etc/default/cis-hardening ]; then # shellcheck source=../../debian/default diff --git a/bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh b/bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh index 8c1f9e36..3c5974ad 100755 --- a/bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh +++ b/bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh @@ -6,7 +6,7 @@ # # -# 99.5.4.5.2 Check that any password that may exist in /etc/shadow is SHA512 hashed and salted +# 99.5.4.5.2 Check that passwords in /etc/shadow are sha512crypt (or yescrypt for Debian 11+) hashed and salted # set -e # One error, it's over @@ -15,7 +15,7 @@ set -u # One variable unset, it's over # shellcheck disable=2034 HARDENING_LEVEL=2 # shellcheck disable=2034 -DESCRIPTION="Check that any password that may exist in /etc/shadow is SHA512 hashed and salted" +DESCRIPTION="Check that passwords in /etc/shadow are sha512crypt (or yescrypt for Debian 11+) hashed and salted" FILE="/etc/shadow" # This function will be called if the script status is on enabled / audit mode @@ -36,13 +36,21 @@ audit() { elif [[ $passwd =~ ^!.*$ ]]; then pw_found+="$user " ok "User $user has a disabled password." - # Check password against $6$$, see `man 3 crypt` + # yescrypt: Check password against $y$$ + elif [ "$DEB_MAJ_VER" -ge "11" ] && [[ $passwd =~ ^\$y\$[./A-Za-z0-9]+\$[./A-Za-z0-9]{,86}\$[./A-Za-z0-9]{43} ]]; then + pw_found+="$user " + ok "User $user has suitable yescrypt hashed password." + # sha512: Check password against $6$$, see `man 3 crypt` elif [[ $passwd =~ ^\$6(\$rounds=[0-9]+)?\$[a-zA-Z0-9./]{2,16}\$[a-zA-Z0-9./]{86}$ ]]; then pw_found+="$user " - ok "User $user has suitable SHA512 hashed password." + ok "User $user has suitable sha512crypt hashed password." else pw_found+="$user " - crit "User $user has a password that is not SHA512 hashed." + if [ "$DEB_MAJ_VER" -ge "11" ]; then + crit "User $user has a password that is not sha512crypt nor yescrypt hashed." + else + crit "User $user has a password that is not sha512crypt hashed." + fi fi done if [[ -z "$users_reviewed" ]]; then diff --git a/tests/hardening/5.3.4_acc_pam_sha512.sh b/tests/hardening/5.3.4_acc_pam_sha512.sh index f8c7dea9..6c8b92a2 100644 --- a/tests/hardening/5.3.4_acc_pam_sha512.sh +++ b/tests/hardening/5.3.4_acc_pam_sha512.sh @@ -3,7 +3,7 @@ test_audit() { describe Running on blank host register_test retvalshouldbe 0 - register_test contain REGEX "[ OK ] .*(sha512|yescrypt) is present in /etc/pam.d/common-password" + register_test contain "is present in /etc/pam.d/common-password" # shellcheck disable=2154 run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all } diff --git a/tests/hardening/99.5.4.5.1_acc_logindefs_sha512.sh b/tests/hardening/99.5.4.5.1_acc_logindefs_sha512.sh index b5ce731e..e972dec1 100644 --- a/tests/hardening/99.5.4.5.1_acc_logindefs_sha512.sh +++ b/tests/hardening/99.5.4.5.1_acc_logindefs_sha512.sh @@ -3,7 +3,7 @@ test_audit() { describe Running on blank host register_test retvalshouldbe 0 - register_test contain "ENCRYPT_METHOD SHA512 is present in /etc/login.defs" + register_test contain "ENCRYPT_METHOD (SHA512|yescrypt|YESCRYPT) is present in /etc/login.defs" # shellcheck disable=2154 run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all @@ -11,7 +11,7 @@ test_audit() { describe Line as comment sed -i 's/\(ENCRYPT_METHOD SHA512\)/# \1/' /etc/login.defs register_test retvalshouldbe 1 - register_test contain "SHA512 is not present" + register_test contain "ENCRYPT_METHOD (SHA512|yescrypt|YESCRYPT) is not present" run commented "${CIS_CHECKS_DIR}/${script}.sh" --audit-all rm /etc/login.defs @@ -24,7 +24,7 @@ test_audit() { sed -ir 's/ENCRYPT_METHOD[[:space:]]\+SHA512/ENCRYPT_METHOD MD5/' /etc/login.defs describe Fail: wrong hash function configuration register_test retvalshouldbe 1 - register_test contain "SHA512 is not present" + register_test contain "ENCRYPT_METHOD (SHA512|yescrypt|YESCRYPT) is not present" run wrongconf "${CIS_CHECKS_DIR}/${script}.sh" --audit-all describe Correcting situation diff --git a/tests/hardening/99.5.4.5.2_acc_shadow_sha512.sh b/tests/hardening/99.5.4.5.2_acc_shadow_sha512.sh index 9b240478..fe91cf59 100644 --- a/tests/hardening/99.5.4.5.2_acc_shadow_sha512.sh +++ b/tests/hardening/99.5.4.5.2_acc_shadow_sha512.sh @@ -12,7 +12,7 @@ test_audit() { sed -i 's/secaudit:!/secaudit:mypassword/' /etc/shadow describe Fail: Found unsecure password register_test retvalshouldbe 1 - register_test contain "User secaudit has a password that is not SHA512 hashed" + register_test contain "User secaudit has a password that is not" run unsecpasswd "${CIS_CHECKS_DIR}/${script}.sh" --audit-all sed -i 's/secaudit:mypassword/secaudit:!!/' /etc/shadow @@ -27,7 +27,7 @@ secaudit:mypassword EOF describe Pass: Found properly hashed password register_test retvalshouldbe 0 - register_test contain "User secaudit has suitable SHA512 hashed password" + register_test contain "User secaudit has suitable" run sha512pass "${CIS_CHECKS_DIR}/${script}.sh" --audit-all chpasswd -c SHA512 -s 1000 <"$outdir/$usecase_name.retval" ret=$(<"$outdir"/"$usecase_name".retval) get_stdout + if [ -s "$outdir/${usecase_name}_err.log" ]; then + echo ">>> stderr follows" + cat "$outdir/${usecase_name}_err.log" + echo "<<< end of stderr" + fi } # Load assertion functions for functionnal tests