Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt all scripts to yescrypt #216

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions bin/hardening/5.3.4_acc_pam_sha512.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
32 changes: 24 additions & 8 deletions bin/hardening/99.5.4.5.1_acc_logindefs_sha512.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)"
Expand All @@ -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
Expand Down
93 changes: 93 additions & 0 deletions bin/hardening/99.5.4.5.2_acc_shadow_sha512.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash

# run-shellcheck
#
# OVH Security audit
#

#
# 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
set -u # One variable unset, it's over

# shellcheck disable=2034
HARDENING_LEVEL=2
# shellcheck disable=2034
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
audit() {
# Review shadow file for existing passwords
pw_found=""
users_reviewed=""
if $SUDO_CMD [ ! -r "$FILE" ]; then
crit "$FILE is not readable"
return
fi
for line in $($SUDO_CMD cut -d ":" -f 1,2 /etc/shadow); do
users_reviewed+="$line "
user=$(echo "$line" | cut -d ":" -f 1)
passwd=$(echo "$line" | cut -d ":" -f 2)
if [[ $passwd = '!' || $passwd = '*' ]]; then
continue
elif [[ $passwd =~ ^!.*$ ]]; then
pw_found+="$user "
ok "User $user has a disabled password."
# yescrypt: Check password against $y$<salt>$<base64>
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$<salt>$<base64>, 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 sha512crypt hashed password."
else
pw_found+="$user "
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
crit "No users were reviewed in $FILE !"
return
fi
if [[ -z "$pw_found" ]]; then
ok "There is no password in $FILE"
fi
}

# This function will be called if the script status is on enabled mode
apply() {
:
}

# This function will check config parameters required
check_config() {
:
}

# Source Root Dir Parameter
if [ -r /etc/default/cis-hardening ]; then
# shellcheck source=../../debian/default
. /etc/default/cis-hardening
fi
if [ -z "$CIS_LIB_DIR" ]; then
echo "There is no /etc/default/cis-hardening file nor cis-hardening directory in current environment."
echo "Cannot source CIS_LIB_DIR variable, aborting."
exit 128
fi

# Main function, will call the proper functions given the configuration (audit, enabled, disabled)
if [ -r "${CIS_LIB_DIR}"/main.sh ]; then
# shellcheck source=../../lib/main.sh
. "${CIS_LIB_DIR}"/main.sh
else
echo "Cannot find main.sh, have you correctly defined your root directory? Current value is $CIS_LIB_DIR in /etc/default/cis-hardening"
exit 128
fi
2 changes: 1 addition & 1 deletion tests/hardening/5.3.4_acc_pam_sha512.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
6 changes: 3 additions & 3 deletions tests/hardening/99.5.4.5.1_acc_logindefs_sha512.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
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 "is present in /etc/login.defs"
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

cp /etc/login.defs /tmp/login.defs.bak
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 "is not present in /etc/login.defs"
run commented "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

rm /etc/login.defs
Expand All @@ -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 "is not present in /etc/login.defs"
run wrongconf "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

describe Correcting situation
Expand Down
40 changes: 40 additions & 0 deletions tests/hardening/99.5.4.5.2_acc_shadow_sha512.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# shellcheck shell=bash
# run-shellcheck
test_audit() {
describe Running on blank host
register_test retvalshouldbe 0
register_test contain "There is no password in /etc/shadow"
dismiss_count_for_test
# shellcheck disable=2154
run blank "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

cp -a /etc/shadow /tmp/shadow.bak
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"
run unsecpasswd "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

sed -i 's/secaudit:mypassword/secaudit:!!/' /etc/shadow
describe Fail: Found disabled password
register_test retvalshouldbe 0
register_test contain "User secaudit has a disabled password"
run lockedpasswd "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

mv /tmp/shadow.bak /etc/shadow
chpasswd -c SHA512 <<EOF
secaudit:mypassword
EOF
describe Pass: Found properly hashed password
register_test retvalshouldbe 0
register_test contain "User secaudit has suitable"
run sha512pass "${CIS_CHECKS_DIR}/${script}.sh" --audit-all

chpasswd -c SHA512 -s 1000 <<EOF
secaudit:mypassword
EOF
describe Pass: Found properly hashed password with custom round number
register_test retvalshouldbe 0
register_test contain "User secaudit has suitable"
run sha512pass "${CIS_CHECKS_DIR}/${script}.sh" --audit-all
}
5 changes: 5 additions & 0 deletions tests/launch_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ _run() {
echo $? >"$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
Expand Down
Loading