content icon indicating copy to clipboard operation
content copied to clipboard

Fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' breaks `passwd`

Open PiRomant opened this issue 1 year ago • 6 comments

Description of problem:

Fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' breaks passwd

SCAP Security Guide Version:

Benchmark Version: 0.1.73

Operating System Version:

Ubuntu 22.04.4 LTS

Steps to Reproduce:

Execute Bash Remediation Script for CIS Ubuntu 22.04 Level 1 Server Benchmark

###############################################################################
# BEGIN fix (42 / 291) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 42/291: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var_password_pam_retry='3'


if [ -e "/etc/pam.d/common-password" ] ; then
    valueRegex="$var_password_pam_retry" defaultValue="$var_password_pam_retry"
    # non-empty values need to be preceded by an equals sign
    [ -n "${valueRegex}" ] && valueRegex="=${valueRegex}"
    # add an equals sign to non-empty values
    [ -n "${defaultValue}" ] && defaultValue="=${defaultValue}"

    # fix 'type' if it's wrong
    if grep -q -P "^\\s*(?"'!'"password\\s)[[:alnum:]]+\\s+[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*)[[:alnum:]]+(\\s+[[:alnum:]]+\\s+pam_pwquality.so)/\\1password\\2/" "/etc/pam.d/common-password"
    fi

    # fix 'control' if it's wrong
    if grep -q -P "^\\s*password\\s+(?"'!'"requisite)[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+)[[:alnum:]]+(\\s+pam_pwquality.so)/\\1requisite\\2/" "/etc/pam.d/common-password"
    fi

    # fix the value for 'option' if one exists but does not match 'valueRegex'
    if grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s)retry=[^[:space:]]*/\\1retry${defaultValue}/" "/etc/pam.d/common-password"

    # add 'option=default' if option is not set
    elif grep -q -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" &&
            grep    -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\sretry(=|\\s|\$)" ; then

        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so[^\\n]*)/\\1 retry${defaultValue}/" "/etc/pam.d/common-password"
    # add a new entry if none exists
    elif ! grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
        echo "password requisite pam_pwquality.so retry${defaultValue}" >> "/etc/pam.d/common-password"
    fi
else
    echo "/etc/pam.d/common-password doesn't exist" >&2
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'

Actual Results:

Remediating rule 42/291: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
# passwd
passwd: Module is unknown
passwd: password unchanged

Expected Results:

# passwd
New password:
Retype new password:

PiRomant avatar Jun 18 '24 13:06 PiRomant

Could you paste more information since I can't reproduce on latest commit of master branch. Here is my generated remediation which is exactly the same:

###############################################################################
# BEGIN fix (44 / 293) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var_password_pam_retry='3'


if [ -e "/etc/pam.d/common-password" ] ; then
    valueRegex="$var_password_pam_retry" defaultValue="$var_password_pam_retry"
    # non-empty values need to be preceded by an equals sign
    [ -n "${valueRegex}" ] && valueRegex="=${valueRegex}"
    # add an equals sign to non-empty values
    [ -n "${defaultValue}" ] && defaultValue="=${defaultValue}"

    # fix 'type' if it's wrong
    if grep -q -P "^\\s*(?"'!'"password\\s)[[:alnum:]]+\\s+[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*)[[:alnum:]]+(\\s+[[:alnum:]]+\\s+pam_pwquality.so)/\\1password\\2/" "/etc/pam.d/common-password"
    fi

    # fix 'control' if it's wrong
    if grep -q -P "^\\s*password\\s+(?"'!'"requisite)[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+)[[:alnum:]]+(\\s+pam_pwquality.so)/\\1requisite\\2/" "/etc/pam.d/common-password"
    fi

    # fix the value for 'option' if one exists but does not match 'valueRegex'
    if grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s)retry=[^[:space:]]*/\\1retry${defaultValue}/" "/etc/pam.d/common-password"

    # add 'option=default' if option is not set
    elif grep -q -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" &&
            grep    -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\sretry(=|\\s|\$)" ; then

        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so[^\\n]*)/\\1 retry${defaultValue}/" "/etc/pam.d/common-password"
    # add a new entry if none exists
    elif ! grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
        echo "password requisite pam_pwquality.so retry${defaultValue}" >> "/etc/pam.d/common-password"
    fi
else
    echo "/etc/pam.d/common-password doesn't exist" >&2
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'

alanmcanonical avatar Jun 28 '24 02:06 alanmcanonical

@alanmcanonical, did you run passwd as root?

PiRomant avatar Jun 28 '24 02:06 PiRomant

Screenshot from 2024-06-28 09-19-41

alanmcanonical avatar Jun 28 '24 08:06 alanmcanonical

FYI: commit: f0c15b27298fd27cc6f9fd5171f81575d7751a5e

build command:

export ADDITIONAL_CMAKE_OPTIONS="-DSSG_SCE_ENABLED:BOOL=ON"
./build_product -j8 ubuntu2204 -o'5.11'

generate the remediation:

cd build
oscap xccdf generate fix --profile cis_level1_server --cpe ssg-ubuntu2204-cpe-dictionary.xml --verbose INFO --verbose-log-file verbose.log --output fix.sh ssg-ubuntu2204-xccdf.xml

alanmcanonical avatar Jun 28 '24 08:06 alanmcanonical

Clear install ubuntu-22.04.4-live-server-amd64. Lets use your https://github.com/ComplianceAsCode/content/issues/12074#issuecomment-2195994583 script

root@ad:/home/ad# nano xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
root@ad:/home/ad# chmod +x xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
# before (I entered mismatched passwords here on purpose)
root@ad:/home/ad# passwd
New password:
Retype new password:
Sorry, passwords do not match.
passwd: Authentication token manipulation error
passwd: password unchanged

root@ad:/home/ad# ./xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
# after
root@ad:/home/ad# passwd
passwd: Module is unknown
passwd: password unchanged

root@ad:/home/ad# cat xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
###############################################################################
# BEGIN fix (44 / 293) for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
###############################################################################
(>&2 echo "Remediating rule 44/293: 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'")
# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var_password_pam_retry='3'


if [ -e "/etc/pam.d/common-password" ] ; then
    valueRegex="$var_password_pam_retry" defaultValue="$var_password_pam_retry"
    # non-empty values need to be preceded by an equals sign
    [ -n "${valueRegex}" ] && valueRegex="=${valueRegex}"
    # add an equals sign to non-empty values
    [ -n "${defaultValue}" ] && defaultValue="=${defaultValue}"

    # fix 'type' if it's wrong
    if grep -q -P "^\\s*(?"'!'"password\\s)[[:alnum:]]+\\s+[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*)[[:alnum:]]+(\\s+[[:alnum:]]+\\s+pam_pwquality.so)/\\1password\\2/" "/etc/pam.d/common-password"
    fi

    # fix 'control' if it's wrong
    if grep -q -P "^\\s*password\\s+(?"'!'"requisite)[[:alnum:]]+\\s+pam_pwquality.so" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+)[[:alnum:]]+(\\s+pam_pwquality.so)/\\1requisite\\2/" "/etc/pam.d/common-password"
    fi

    # fix the value for 'option' if one exists but does not match 'valueRegex'
    if grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry(?"'!'"${valueRegex}(\\s|\$))" < "/etc/pam.d/common-password" ; then
        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s)retry=[^[:space:]]*/\\1retry${defaultValue}/" "/etc/pam.d/common-password"

    # add 'option=default' if option is not set
    elif grep -q -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" &&
            grep    -E "^\\s*password\\s+requisite\\s+pam_pwquality.so" < "/etc/pam.d/common-password" | grep -q -E -v "\\sretry(=|\\s|\$)" ; then

        sed --follow-symlinks -i -E -e "s/^(\\s*password\\s+requisite\\s+pam_pwquality.so[^\\n]*)/\\1 retry${defaultValue}/" "/etc/pam.d/common-password"
    # add a new entry if none exists
    elif ! grep -q -P "^\\s*password\\s+requisite\\s+pam_pwquality.so(\\s.+)?\\s+retry${valueRegex}(\\s|\$)" < "/etc/pam.d/common-password" ; then
        echo "password requisite pam_pwquality.so retry${defaultValue}" >> "/etc/pam.d/common-password"
    fi
else
    echo "/etc/pam.d/common-password doesn't exist" >&2
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi
# END fix for 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry'
root@ad:/home/ad# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
root@ad:/home/ad# history
    1  nano xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
    2  chmod +x xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
    3  passwd
    4  ./xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
    5  passwd
    6  cat xccdf_org.ssgproject.content_rule_accounts_password_pam_retry.sh
    7  cat /etc/os-release
    8  history

PiRomant avatar Jun 28 '24 08:06 PiRomant

@PiRomant do you have libpam-pwquality installed?

dodys avatar Jul 02 '24 08:07 dodys

Screenshot from 2024-07-02 09-40-42

alanmcanonical avatar Jul 02 '24 08:07 alanmcanonical

There is no libpam-pwquality after running the script https://github.com/ComplianceAsCode/content/issues/12074#issuecomment-2195994583.

PiRomant avatar Jul 02 '24 08:07 PiRomant

I don't have libpam-pwquality too

alanmcanonical avatar Jul 02 '24 08:07 alanmcanonical

So, there are 7 pam_pwquality configuration checks, and none of them confirms that it is installed and enabled?

PiRomant avatar Jul 02 '24 08:07 PiRomant

There is no libpam-pwquality after running the script #12074 (comment).

Try installing it, it is part of the whole CIS 5.4.1 solution. Does it solve your issue?

dodys avatar Jul 02 '24 09:07 dodys

Yes, it helps. After installing libpam-pwqualit, none of the remediation below break passwd. However, password restrictions do not apply to root. Root can set a weak password for anyone.

'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minclass' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'

PiRomant avatar Jul 02 '24 10:07 PiRomant

Yes, it helps. After installing libpam-pwqualit, none of the remediation below break passwd. However, password restrictions do not apply to root. Root can set a weak password for anyone.

'xccdf_org.ssgproject.content_rule_accounts_password_pam_dcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_lcredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minclass' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_minlen' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ocredit' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_retry' 'xccdf_org.ssgproject.content_rule_accounts_password_pam_ucredit'

I believe that's by design, if you want root to also follow the same guidelines, you would need to use the enforce_for_root https://linux.die.net/man/8/pam_pwquality

dodys avatar Jul 02 '24 15:07 dodys

Since this is not an issue I'm closing it.

dodys avatar Jul 02 '24 15:07 dodys

But, installing libpam-pwquality is a part of 5.4.1 in v1. https://github.com/user-attachments/files/15899704/CIS_Ubuntu_Linux_22.04_LTS_Benchmark_v1.0.0_5.4.1.pdf image

PiRomant avatar Jul 02 '24 15:07 PiRomant

@PiRomant that is already part of the remediation and profile: https://github.com/ComplianceAsCode/content/blob/master/products/ubuntu2204/profiles/cis_level1_server.profile#L850

It probably just isn't part of version 0.1.73, it will land in the next one

dodys avatar Jul 02 '24 15:07 dodys

if you need more information: https://github.com/ComplianceAsCode/content/pull/11968

dodys avatar Jul 02 '24 16:07 dodys