├── .travis.yml ├── .yamllint ├── LICENSE ├── README.md ├── hack └── test.sh ├── scripts ├── test_section_03_level1 │ └── 3-1-2.sh ├── test_section_05_level1 │ ├── 5-2-2.sh │ ├── 5-2-3.sh │ ├── 5-4-1-5.sh │ └── 5-4-4.sh └── test_section_06_level1 │ ├── 6-1-13.sh │ ├── 6-1-14.sh │ ├── 6-2-10.sh │ ├── 6-2-11.sh │ ├── 6-2-12.sh │ ├── 6-2-13.sh │ ├── 6-2-14.sh │ ├── 6-2-15.sh │ ├── 6-2-16.sh │ ├── 6-2-3.sh │ ├── 6-2-4.sh │ ├── 6-2-5.sh │ ├── 6-2-6.sh │ ├── 6-2-7.sh │ ├── 6-2-8.sh │ └── 6-2-9.sh ├── test_section_01_level1.yml ├── test_section_02_level1.yml ├── test_section_03_level1.yml ├── test_section_05_level1.yml └── test_section_06_level1.yml /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | before_install: 4 | - sudo curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.13/goss-linux-amd64 -o /usr/local/bin/goss 5 | - sudo chmod +rx /usr/local/bin/goss 6 | install: 7 | - pip install yamllint 8 | script: 9 | - yamllint --strict . 10 | - bash hack/test.sh 11 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | braces: 6 | max-spaces-inside: 1 7 | level: error 8 | brackets: 9 | max-spaces-inside: 1 10 | level: error 11 | line-length: disable 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Neoway Business Solution Laboratory 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | goss-cis-benchmark 2 | === 3 | 4 | [![Build Status](https://travis-ci.org/NeowayLabs/goss-cis-benchmark.svg?branch=master)](https://travis-ci.org/NeowayLabs/goss-cis-benchmark) 5 | 6 | This project validate level 1 for the sections 1, 2, 3, 5 and 6 of Ubuntu CIS Controls Benchmarks with [Goss](https://github.com/aelsabbahy/goss). 7 | 8 | Currently supports version 20.04 of Ubuntu Server. 9 | 10 | ## Items not implemented 11 | 12 | ### Section 1 13 | 14 | * 1.2.1 Ensure package manager repositories are configured (Manual): not implemented 15 | * 1.2.2 Ensure GPG keys are configured (Manual): not implemented 16 | * 1.4.1 Ensure AIDE is installed (Automated) : not implemented 17 | * 1.4.2 Ensure filesystem integrity is regularly checked (Automated): not implemented 18 | * 1.5.1 Ensure bootloader password is set (Automated): not implemented 19 | * 1.5.2 Ensure permissions on bootloader config are configured (Automated): not implemented 20 | * 1.5.3 Ensure authentication required for single user mode (Automated): not implemented 21 | 22 | ### Section 2 23 | 24 | * 2.2.1.2 Ensure systemd-timesyncd is configured (Manual): not implemented 25 | * 2.2.1.4 Ensure ntp is configured (Automated): not implemented 26 | * 2.4 Ensure nonessential services are removed or masked (Manual): not implemented 27 | 28 | ### Section 3 29 | 30 | * 3.5.1.1 Ensure Uncomplicated Firewall is installed (Automated): not implemented 31 | * 3.5.1.2 Ensure iptables-persistent is not installed (Automated): not implemented 32 | * 3.5.1.3 Ensure ufw service is enabled (Automated): not implemented 33 | * 3.5.1.4 Ensure loopback traffic is configured (Automated): not implemented 34 | * 3.5.1.5 Ensure outbound connections are configured (Manual): not implemented 35 | * 3.5.1.6 Ensure firewall rules exist for all open ports (Manual): not implemented 36 | * 3.5.1.7 Ensure default deny firewall policy (Automated): not implemented 37 | * 3.5.2.1 Ensure nftables is installed (Automated): not implemented 38 | * 3.5.2.2 Ensure Uncomplicated Firewall is not installed or disabled (Automated): not implemented 39 | * 3.5.2.3 Ensure iptables are flushed (Manual): not implemented 40 | * 3.5.2.4 Ensure a table exists (Automated): not implemented 41 | * 3.5.2.5 Ensure base chains exist (Automated): not implemented 42 | * 3.5.2.6 Ensure loopback traffic is configured (Automated): not implemented 43 | * 3.5.2.7 Ensure outbound and established connections are configured (Manual): not implemented 44 | * 3.5.2.8 Ensure default deny firewall policy (Automated): not implemented 45 | * 3.5.2.9 Ensure nftables service is enabled (Automated): not implemented 46 | * 3.5.2.10 Ensure nftables rules are permanent (Automated): not implemented 47 | * 3.5.3.1.1 Ensure iptables packages are installed (Automated): not implemented 48 | * 3.5.3.1.2 Ensure nftables is not installed (Automated): not implemented 49 | * 3.5.3.1.3 Ensure Uncomplicated Firewall is not installed or disabled (Automated): not implemented 50 | * 3.5.3.2.1 Ensure default deny firewall policy (Automated): not implemented 51 | * 3.5.3.2.2 Ensure loopback traffic is configured (Automated): not implemented 52 | * 3.5.3.2.4 Ensure firewall rules exist for all open ports (Automated): not implemented 53 | * 3.5.3.3.1 Ensure IPv6 default deny firewall policy (Automated): not implemented 54 | * 3.5.3.3.2 Ensure IPv6 loopback traffic is configured (Automated): not implemented 55 | * 3.5.3.3.3 Ensure IPv6 outbound and established connections are configured (Manual): not implemented 56 | * 3.5.3.3.4 Ensure IPv6 firewall rules exist for all open ports (Manual): not implemented 57 | 58 | ### Section 5 59 | 60 | * 5.3.2 Ensure lockout for failed password attempts is configured (Automated) : not implemented 61 | * 5.3.3 Ensure password reuse is limited (Automated): not implemented 62 | * 5.3.4 Ensure password hashing algorithm is SHA-512 (Automated): not implemented 63 | * 5.4.1.4 Ensure inactive password lock is 30 days or less (Automated): not implemented 64 | * 5.4.1.1 Ensure password expiration is 365 days or less (Automated): not implemented 65 | * 5.4.1.5 Ensure all users last password change date is in the past (Automated): not implemented 66 | * 5.4.2 Ensure system accounts are secured (Automated): not implemented 67 | * 5.4.5 Ensure default user shell timeout is 900 seconds or less (Automated): not implemented 68 | * 5.6 Ensure access to the su command is restricted (Automated): not implemented 69 | * 5.5 Ensure root login is restricted to system console (Manual): not implemented 70 | * 5.6 Ensure access to the su command is restricted (Automated): not implemented 71 | 72 | ## Requirements 73 | 74 | * [Goss](https://github.com/aelsabbahy/goss#installation) 75 | * Bash 76 | 77 | ## Usage 78 | 79 | ### Clone this repository 80 | 81 | ```shell 82 | git clone https://github.com/NeowayLabs/goss-cis-benchmark 83 | ``` 84 | 85 | ```shell 86 | cd goss-cis-benchmark 87 | cp -r ./scripts/* /tmp 88 | goss --gossfile test_section_01_level1.yml validate 89 | goss --gossfile test_section_02_level1.yml validate 90 | goss --gossfile test_section_03_level1.yml validate 91 | goss --gossfile test_section_05_level1.yml validate 92 | goss --gossfile test_section_06_level1.yml validate 93 | ``` 94 | -------------------------------------------------------------------------------- /hack/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | status="0" 7 | test_fail="0" 8 | 9 | for f in $(find -name "test_*.yml"); do 10 | status="0" 11 | echo "" 12 | echo "Running: goss --gossfile ${f} render" 13 | echo "" 14 | goss --gossfile ${f} render || status="1" 15 | if test ${status} = "0"; then 16 | echo "" 17 | echo "Test pass" 18 | echo "---" 19 | else 20 | echo "" 21 | echo "Test fail" 22 | test_fail="true" 23 | echo "---" 24 | fi 25 | done 26 | 27 | if test ${test_fail} = "true"; then 28 | echo "" 29 | echo "One or more tests failed! Check the output above." 30 | exit 1 31 | else 32 | echo "" 33 | echo "All tests passed" 34 | exit 0 35 | fi 36 | -------------------------------------------------------------------------------- /scripts/test_section_03_level1/3-1-2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 3.1.2 Ensure wireless interfaces are disabled (Automated) 4 | # 5 | # Description: 6 | # Wireless networking is used when wired networks are unavailable. Ubuntu 7 | # contains a wireless tool kit to allow system administrators to configure 8 | # and use wireless networks. 9 | # 10 | # Rationale: 11 | # If wireless is not to be used, wireless devices can be disabled to reduce 12 | # the potential attack surface. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | dm="" 18 | driverdir="" 19 | drivers="" 20 | status="0" 21 | t="0" 22 | 23 | command -v nmcli >/dev/null 2>&1 || status="1" 24 | 25 | if [[ "${status}" -eq 0 ]]; then 26 | nmcli radio all | grep -Eq '\s*\S+\s+disabled\s+\S+\s+disabled\b' || status="1" 27 | if [[ "${status}" -eq 1 ]]; then 28 | echo "Wireless is not enabled" 29 | fi 30 | elif [[ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]]; then 31 | drivers=$(for driverdir in $(find /sys/class/net/*/ -type d -name wireless | xargs -0 dirname); do basename "$(readlink -f "${driverdir}"/device/driver)"; done | sort -u) 32 | for dm in ${drivers}; do 33 | if grep -Eq "^\s*install\s+${dm}\s+/bin/(true|false)" /etc/modprobe.d/*.conf; then 34 | /bin/true 35 | else 36 | echo "${dm} is not disabled" 37 | t="1" 38 | fi 39 | done 40 | if [[ "${t}" -eq 0 ]]; then 41 | echo "Wireless is not enabled" 42 | fi 43 | else 44 | echo "Wireless is not enabled" 45 | fi 46 | -------------------------------------------------------------------------------- /scripts/test_section_05_level1/5-2-2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 5.2.2 Ensure permissions on SSH private host key files are 4 | # configured (Automated) 5 | # 6 | # Description: 7 | # An SSH private key is one of two files used in SSH public key authentication. 8 | # In this authentication method, The possession of the private key is proof of 9 | # identity. Only a private key that corresponds to a public key will be able to 10 | # authenticate successfully. The private keys need to be stored and handled 11 | # carefully, and no copies of the private key should be distributed. 12 | # 13 | # Rationale: 14 | # If an unauthorized user obtains the private SSH host key file, the host could 15 | # be impersonated 16 | 17 | set -o errexit 18 | set -o nounset 19 | 20 | file="" 21 | files="" 22 | stat_file="" 23 | status="0" 24 | t="0" 25 | 26 | files=$(find /etc/ssh -xdev -type f -name 'ssh_host_*_key') || status="1" 27 | if [ "${status}" -eq 0 ]; then 28 | if [ -n "${files}" ]; then 29 | for file in ${files}; do 30 | stat_file=$(stat -c "%a-%u-%g-%U-%G" "${file}") || status="1" 31 | if [ -n "${stat_file}" ]; then 32 | if [ "${stat_file}" = "600-0-0-root-root" ]; then 33 | /bin/true 34 | else 35 | echo "${file} ownership or permissions is wrong" 36 | t="1" 37 | fi 38 | fi 39 | done 40 | fi 41 | if [ "${t}" -eq 0 ]; then 42 | echo "Ownership and permissions of private key are correct" 43 | fi 44 | else 45 | echo "Ownership and permissions of private key are correct" 46 | fi 47 | -------------------------------------------------------------------------------- /scripts/test_section_05_level1/5-2-3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 5.2.3 Ensure permissions on SSH public host key files are configured 4 | # configured (Automated) 5 | # 6 | # Description: 7 | # An SSH public key is one of two files used in SSH public key authentication. 8 | # In this authentication method, a public key is a key that can be used for 9 | # verifying digital signatures generated using a corresponding private key. Only 10 | # a public key that corresponds to a private key will be able to authenticate 11 | # successfully. 12 | # 13 | # Rationale: 14 | # If a public host key file is modified by an unauthorized user, the SSH service 15 | # may be compromised. 16 | 17 | set -o errexit 18 | set -o nounset 19 | 20 | file="" 21 | files="" 22 | stat_file="" 23 | status="0" 24 | t="0" 25 | 26 | files=$(find /etc/ssh -xdev -type f -name 'ssh_host_*_key.pub') || status="1" 27 | if [ "${status}" -eq 0 ]; then 28 | if [ -n "${files}" ]; then 29 | for file in ${files}; do 30 | stat_file=$(stat -c "%a-%u-%g-%U-%G" "${file}") || status="1" 31 | if [ -n "${stat_file}" ]; then 32 | if [ "${stat_file}" = "600-0-0-root-root" ]; then 33 | /bin/true 34 | else 35 | echo "${file} ownership or permissions is wrong" 36 | t="1" 37 | fi 38 | fi 39 | done 40 | fi 41 | if [ "${t}" -eq 0 ]; then 42 | echo "Ownership and permissions of public key are correct" 43 | fi 44 | else 45 | echo "Ownership and permissions of public key are correct" 46 | fi 47 | -------------------------------------------------------------------------------- /scripts/test_section_05_level1/5-4-1-5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 5.4.1.5 Ensure all users last password change date is in the past (Automated) 4 | # 5 | # Description: 6 | # All users should have a password change date in the past. 7 | # 8 | # Rationale: 9 | # If a users recorded password change date is in the future then they could 10 | # bypass any set password expiration. 11 | 12 | set -o errexit 13 | set -o nounset 14 | 15 | for usr in $(cut -d: -f1 /etc/shadow); do 16 | [[ \ 17 | $(chage --list $usr | grep '^Last password change' | cut -d: -f2) > $(date) 18 | ]] \ 19 | && \ 20 | echo "$usr :$(chage --list $usr | grep '^Last password change' | cut -d: -f2)"; 21 | done 22 | -------------------------------------------------------------------------------- /scripts/test_section_05_level1/5-4-4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 5.4.4 Ensure default user umask is 027 or more restrictive (Automated) 4 | # 5 | # Description: 6 | # The user file-creation mode mask ( umask ) is use to determine the file 7 | # permission for newly created directories and files. In Linux, the default 8 | # permissions for any newly created directory is 0777 (rwxrwxrwx), and for any 9 | # newly created file it is 0666 (rw-rw-rw-). The umask modifies the default Linux 10 | # permissions by restricting (masking) these permissions. The umask is not simply 11 | # subtracted, but is processed bitwise. Bits set in the umask are cleared in the 12 | # resulting file mode. 13 | # 14 | # Rationale: 15 | # Setting a very secure default value for umask ensures that users make a 16 | # conscious choice about their file permissions. A default umask setting of 077 17 | # causes files and directories created by users to not be readable by any other 18 | # user on the system. A umask of 027 would make files and directories readable by 19 | # users in the same Unix group, while a umask of 022 would make files readable by 20 | # every user on the system. 21 | 22 | set -o errexit 23 | set -o nounset 24 | 25 | passing="" 26 | 27 | grep --extended-regexp \ 28 | --ignore-case \ 29 | --quiet \ 30 | '^\s*UMASK\s+(0[0-7][2-7]7|[0-7][2-7]7)\b' \ 31 | /etc/login.defs && \ 32 | grep --extended-regexp \ 33 | --quiet \ 34 | '^\s*session\s+(optional|requisite|required)\s+pam_umask\.so\b' \ 35 | /etc/pam.d/common-session \ 36 | && \ 37 | passing="true" 38 | 39 | grep --dereference-recursive \ 40 | --extended-regexp \ 41 | --ignore-case \ 42 | --quiet \ 43 | '^\s*UMASK\s+\s*(0[0-7][2-7]7|[0-7][2-7]7|u=(r?|w?|x?)(r?|w?|x?)(r?|w?|x?),g=(r?x?|x?r?),o=)\b' \ 44 | /etc/profile* /etc/bash.bashrc* \ 45 | && \ 46 | passing="true" 47 | 48 | [ "$passing" = "true" ] && echo "Default user umask is set" 49 | 50 | grep --dereference-recursive \ 51 | --ignore-case \ 52 | --perl-regexp \ 53 | '(^|^[^#]*)\s*umask\s+([0-7][0-7][01][0-7]\b|[0-7][0-7][0-7][0-6]\b|[0-7][01][0-7]\b|[0-7][0-7][0-6]\b|(u=[rwx]{0,3},)?(g=[rwx]{0,3},)?o=[rwx]+\b|(u=[rwx]{1,3},)?g=[^rx]{1,3}(,o=[rwx]{0,3})?\b)' \ 54 | /etc/login.defs \ 55 | /etc/profile* \ 56 | /etc/bash.bashrc* 57 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-1-13.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.1.13 Audit SUID executables (Manual) 4 | # 5 | # Description: 6 | # The owner of a file can set the file's permissions to run with the owner's or 7 | # group's permissions, even if the user running the program is not the owner or 8 | # a member of the group. 9 | # The most common reason for a SUID program is to enable users to perform 10 | # functions (such as changing their password) that require root privileges. 11 | # 12 | # Rationale: 13 | # There are valid reasons for SUID programs, but it is important to identify 14 | # and review such programs to ensure they are legitimate. 15 | 16 | set -o errexit 17 | set -o nounset 18 | 19 | declare gcp_binaries="29" 20 | declare azure_binaries="13" 21 | declare url_google="http://metadata/computeMetadata/v1/instance/hostname" 22 | status=0 23 | 24 | count_SUID=$(df --local -P | awk "{'if (NR!=1) print $6'}" | xargs -I '{}' find '{}' -xdev -type f -perm -4000 | wc -l) 25 | 26 | curl -v -H Metadata-Flavor:Google $url_google -f > /dev/null 2>&1 || status=1 27 | 28 | if [[ "${status}x" == "0x" ]]; then 29 | if [[ $count_SUID == "$gcp_binaries" ]]; then 30 | exit 1 31 | else 32 | exit 0 33 | fi 34 | fi 35 | 36 | if [[ $count_SUID == "$azure_binaries" ]]; then 37 | exit 1 38 | else 39 | exit 0 40 | fi 41 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-1-14.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.1.14 Audit SGID executables (Manual) 4 | # 5 | # Description: 6 | # The owner of a file can set the file's permissions to run with the owner's or 7 | # group's permissions, even if the user running the program is not the owner or 8 | # a member of the group. The most common reason for a SGID program is to enable 9 | # users to perform functions (such as changing their password) that require root 10 | # privileges. 11 | # 12 | # Rationale: 13 | # There are valid reasons for SGID programs, but it is important to identify and 14 | # review such programs to ensure they are legitimate. Review the files returned 15 | # by the action in the audit section and check to see if system binaries have a 16 | # different md5 checksum than what from the package. This is an indication that 17 | # the binary may have been replaced. 18 | 19 | set -o errexit 20 | set -o nounset 21 | 22 | declare gcp_binaries="14" 23 | declare azure_binaries="8" 24 | declare url_google="http://metadata/computeMetadata/v1/instance/hostname" 25 | status=0 26 | 27 | count_SGID=$(df --local -P | awk "{'if (NR!=1) print $6'}" | xargs -I '{}' find '{}' -xdev -type f -perm -2000 | wc -l) 28 | 29 | curl -v -H Metadata-Flavor:Google $url_google -f > /dev/null 2>&1 || status=1 30 | 31 | if [[ "${status}x" == "0x" ]]; then 32 | if [[ $count_SGID == "$gcp_binaries" ]]; then 33 | exit 1 34 | else 35 | exit 0 36 | fi 37 | fi 38 | 39 | if [[ $count_SGID == "$azure_binaries" ]]; then 40 | exit 1 41 | else 42 | exit 0 43 | fi 44 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.10 Ensure users' .netrc Files are not group or world accessible (Automated) 4 | # 5 | # Description: 6 | # While the system administrator can establish secure permissions for users' 7 | # .netrc files, the users can easily override these. 8 | # 9 | # Rationale: 10 | # .netrc files may contain unencrypted passwords that may be used to attack other 11 | # systems. 12 | 13 | set -o errexit 14 | set -o nounset 15 | 16 | declare dir="" 17 | declare file="" 18 | declare fileperm="" 19 | declare line="" 20 | declare status="0" 21 | declare stderr="0" 22 | declare user="" 23 | declare vars="" 24 | 25 | while read line; do 26 | 27 | vars=$( 28 | echo ${line} | \ 29 | egrep -v '^(root|halt|sync|shutdown)' | \ 30 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 31 | ) || status=1 32 | 33 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 34 | set -- ${vars} 35 | user=${1-} && dir=${2-} 36 | if [ ! -d ${dir} ]; then 37 | echo "The home directory (${dir}) of user ${user} does not exist." 38 | stderr="1" 39 | else 40 | for file in ${dir}/.netrc; do 41 | if [ ! -h "${file}" -a -f "${file}" ]; then 42 | fileperm=$(ls -ld ${file} | cut -f1 -d" ") 43 | if [ $(echo ${fileperm} | cut -c5) != "-" ]; then 44 | echo "Group Read set on ${file}" 45 | stderr="1" 46 | fi 47 | if [ $(echo ${fileperm} | cut -c6) != "-" ]; then 48 | echo "Group Write set on ${file}" 49 | stderr="1" 50 | fi 51 | if [ $(echo ${fileperm} | cut -c7) != "-" ]; then 52 | echo "Group Execute set on ${file}" 53 | stderr="1" 54 | fi 55 | if [ $(echo ${fileperm} | cut -c8) != "-" ]; then 56 | echo "Other Read set on ${file}" 57 | stderr="1" 58 | fi 59 | if [ $(echo ${fileperm} | cut -c9) != "-" ]; then 60 | echo "Other Write set on ${file}" 61 | stderr="1" 62 | fi 63 | if [ $(echo ${fileperm} | cut -c10) != "-" ]; then 64 | echo "Other Execute set on ${file}" 65 | stderr="1" 66 | fi 67 | fi 68 | done 69 | fi 70 | fi 71 | 72 | done < /etc/passwd 73 | 74 | if [ ${stderr} != "0" ]; then 75 | exit 1 76 | fi 77 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-11.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.11 Ensure no users have .rhosts files (Automated) 4 | # 5 | # Description: 6 | # While no .rhosts files are shipped by default, users can easily create them. 7 | # 8 | # Rationale: 9 | # This action is only meaningful if .rhosts support is permitted in the file 10 | # /etc/pam.conf. Even though the .rhosts files are ineffective if support is 11 | # disabled in /etc/pam.conf , they may have been brought over from other systems 12 | # and could contain information useful to an attacker for those other systems. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare dir="" 18 | declare file="" 19 | declare line="" 20 | declare status="0" 21 | declare stderr="0" 22 | declare user="" 23 | declare vars="" 24 | 25 | while read line; do 26 | 27 | vars=$( 28 | echo ${line} | \ 29 | egrep -v '^(root|halt|sync|shutdown)' | \ 30 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 31 | ) || status=1 32 | 33 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 34 | set -- ${vars} 35 | user=${1-} && dir=${2-} 36 | if [ ! -d ${dir} ]; then 37 | echo "The home directory (${dir}) of user ${user} does not exist." 38 | stderr="1" 39 | else 40 | for file in ${dir}/.rhosts; do 41 | if [ ! -h "${file}" -a -f "${file}" ]; then 42 | echo ".rhosts file in ${dir}" 43 | stderr="1" 44 | fi 45 | done 46 | fi 47 | fi 48 | 49 | done < /etc/passwd 50 | 51 | if [ ${stderr} != "0" ]; then 52 | exit 1 53 | fi 54 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-12.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.12 Ensure all groups in /etc/passwd exist in /etc/group (Automated) 4 | # 5 | # Description: 6 | # Over time, system administration errors and changes can lead to groups being 7 | # defined in /etc/passwd but not in /etc/group. 8 | # 9 | # Rationale: 10 | # Groups defined in the /etc/passwd file but not in the /etc/group file pose a 11 | # threat to system security since group permissions are not properly managed. 12 | 13 | set -o errexit 14 | set -o nounset 15 | 16 | declare i="" 17 | declare status="0" 18 | declare stderr="0" 19 | 20 | for i in $(cut -s -d: -f4 /etc/passwd | sort -u ); do 21 | grep -q -P "^.*?:[^:]*:$i:" /etc/group || status=1 22 | if [ ${status} -ne 0 ]; then 23 | echo "Group ${i} is referenced by /etc/passwd but does not exist in /etc/group" 24 | stderr="1" 25 | fi 26 | done 27 | 28 | if [ ${stderr} != "0" ]; then 29 | exit 1 30 | fi 31 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-13.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.13 Ensure no duplicate UIDs exist (Automated) 4 | # 5 | # Description: 6 | # Although the useradd program will not let you create a duplicate 7 | # User ID (UID), it is possible for an administrator to manually edit 8 | # the /etc/passwd file and change the UID field. 9 | # 10 | # Rationale: 11 | # Users must be assigned unique UIDs for accountability and to ensure appropriate 12 | # access protections. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare id="" 18 | declare l="" 19 | declare line="" 20 | declare qtd="" 21 | declare status="0" 22 | declare stderr="0" 23 | declare users="" 24 | 25 | line=$(cut -f3 -d":" /etc/passwd | sort -n | uniq -c | awk '{printf $1" "$2"@"}' |sed 's#@$##g') || status=1 26 | 27 | if [ ${status} = "0" ]; then 28 | 29 | IFS="@" 30 | for l in ${line}; do 31 | IFS=" " && set - ${l} 32 | qtd=${1-} && id=${2-} 33 | if [ ${qtd} -gt 1 ]; then 34 | users=$(awk -F: '($3 == n) { print $1 }' n=${id} /etc/passwd | xargs) 35 | echo "Duplicate UID (${id}): ${users}" 36 | stderr="1" 37 | fi 38 | done 39 | 40 | fi 41 | 42 | if [ ${stderr} != "0" ]; then 43 | exit 1 44 | fi 45 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-14.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.14 Ensure no duplicate GIDs exist (Automated) 4 | # 5 | # Description: 6 | # Although the groupadd program will not let you create a duplicate 7 | # Group ID (GID), it is possible for an administrator to manually 8 | # edit the /etc/group file and change the GID field. 9 | # 10 | # Rationale: 11 | # User groups must be assigned unique GIDs for accountability and to ensure 12 | # appropriate access protections. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare groups="" 18 | declare id="" 19 | declare l="" 20 | declare line="" 21 | declare qtd="" 22 | declare status="0" 23 | declare stderr="0" 24 | 25 | line=$(cut -f3 -d":" /etc/group | sort -n | uniq -c | awk '{printf $1" "$2"@"}' |sed 's#@$##g') || status=1 26 | 27 | if [ ${status} = "0" ]; then 28 | 29 | IFS="@" 30 | for l in ${line}; do 31 | IFS=" " && set - ${l} 32 | qtd=${1-} && id=${2-} 33 | if [ ${qtd} -gt 1 ]; then 34 | groups=$(awk -F: '($3 == n) { print $1 }' n=${id} /etc/group | xargs) 35 | echo "Duplicate GID (${id}): ${groups}" 36 | stderr="1" 37 | fi 38 | done 39 | 40 | fi 41 | 42 | if [ ${stderr} != "0" ]; then 43 | exit 1 44 | fi 45 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-15.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.15 Ensure no duplicate user names exist (Automated) 4 | # 5 | # Description: 6 | # Although the useradd program will not let you create a duplicate user name, it 7 | # is possible for an administrator to manually edit the /etc/passwd file and 8 | # change the user name. 9 | # 10 | # Rationale: 11 | # If a user is assigned a duplicate user name, it will create and have access to 12 | # files with the first UID for that username in /etc/passwd . For example, if 13 | # "test4" has a UID of 1000 and a subsequent "test4" entry has a UID of 2000, 14 | # logging in as "test4" will use UID 1000. Effectively, the UID is shared, which 15 | # is a security problem. 16 | 17 | set -o errexit 18 | set -o nounset 19 | 20 | declare l="" 21 | declare line="" 22 | declare qtd="" 23 | declare status="0" 24 | declare stderr="0" 25 | declare uids="" 26 | declare user="" 27 | 28 | line=$(cut -f1 -d":" /etc/passwd | sort -n | uniq -c | awk '{printf $1" "$2"@"}' |sed 's#@$##g') || status=1 29 | 30 | if [ ${status} = "0" ]; then 31 | 32 | IFS="@" 33 | for l in ${line}; do 34 | IFS=" " && set - ${l} 35 | qtd=${1-} && user=${2-} 36 | if [ ${qtd} -gt 1 ]; then 37 | uids=$(awk -F: '($1 == n) { print $3 }' n=${user} /etc/passwd | xargs) 38 | echo "Duplicate User Name (${user}): ${uids}" 39 | stderr="1" 40 | fi 41 | done 42 | 43 | fi 44 | 45 | if [ ${stderr} != "0" ]; then 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-16.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.16 Ensure no duplicate group names exist (Automated) 4 | # 5 | # Description: 6 | # Although the groupadd program will not let you create a duplicate group name, 7 | # it is possible for an administrator to manually edit the /etc/group file and 8 | # change the group name. 9 | # 10 | # Rationale: 11 | # If a group is assigned a duplicate group name, it will create and have access 12 | # to files with the first GID for that group in /etc/group . Effectively, the 13 | # GID is shared, which is a security problem. 14 | 15 | set -o errexit 16 | set -o nounset 17 | 18 | declare gids="" 19 | declare group="" 20 | declare l="" 21 | declare line="" 22 | declare qtd="" 23 | declare status="0" 24 | declare stderr="0" 25 | 26 | line=$(cut -f1 -d":" /etc/group | sort -n | uniq -c | awk '{printf $1" "$2"@"}' |sed 's#@$##g') || status=1 27 | 28 | if [ ${status} = "0" ]; then 29 | 30 | IFS="@" 31 | for l in ${line}; do 32 | IFS=" " && set - ${l} 33 | qtd=${1-} && group=${2-} 34 | if [ ${qtd} -gt 1 ]; then 35 | gids=$(awk -F: '($1 == n) { print $3 }' n=${group} /etc/group | xargs) 36 | echo "Duplicate Group Name (${group}): ${gids}" 37 | stderr="1" 38 | fi 39 | done 40 | 41 | fi 42 | 43 | if [ ${stderr} != "0" ]; then 44 | exit 1 45 | fi 46 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.3 Ensure root PATH Integrity (Automated) 4 | # 5 | # Description: 6 | # The root user can execute any command on the system and could be fooled into 7 | # executing programs unintentionally if the PATH is not set correctly. 8 | # 9 | # Rationale: 10 | # Including the current working directory (.) or other writable directory in 11 | # root 's executable path makes it likely that an attacker can gain superuser 12 | # access by forcing an administrator operating as root to execute a Trojan horse 13 | # program. 14 | 15 | set -o errexit 16 | set -o nounset 17 | 18 | declare dirown="" 19 | declare dirperm="" 20 | declare p="" 21 | declare path="" 22 | declare status="0" 23 | declare stderr="0" 24 | 25 | echo ${PATH} | grep "::" > /dev/null 2>&1 && status=1 26 | 27 | if [ ${status} != "0" ]; then 28 | echo "Empty Directory in PATH (::)" 29 | stderr="1" 30 | fi 31 | 32 | echo $PATH | grep ":$" > /dev/null 2>&1 && status=1 33 | 34 | if [ ${status} != "0" ]; then 35 | echo "Trailing : in PATH" 36 | stderr="1" 37 | fi 38 | 39 | path=$(echo ${PATH} | sed -e 's/::/:/' -e 's/:$//' -e 's/:/ /g') 40 | set -- ${path} 41 | while [ "${1-}" != "" ]; do 42 | p=${1-} 43 | if [ "${p}" = "." ]; then 44 | echo "PATH contains ." 45 | shift 46 | continue 47 | fi 48 | if [ -d "${p}" ]; then 49 | dirperm=$(ls -ldH ${p} | cut -f1 -d" ") 50 | echo ${dirperm} | cut -c6 | grep "-" > /dev/null 2>&1 || status=1 51 | if [ ${status} != "0" ]; then 52 | echo "Group Write permission set on directory ${p}" 53 | stderr="1" 54 | fi 55 | echo ${dirperm} | cut -c9 | grep "-" > /dev/null 2>&1 || status=1 56 | if [ ${status} != "0" ]; then 57 | echo "Other Write permission set on directory ${p}" 58 | stderr="1" 59 | fi 60 | dirown=$(ls -ldH ${p} | awk '{print $3}') || status=1 61 | if [ ${status} = "0" ]; then 62 | if [ "${dirown}" != "root" ] ; then 63 | echo "${p} is not owned by root" 64 | stderr="1" 65 | fi 66 | fi 67 | else 68 | echo "${p} is not a directory" 69 | stderr="1" 70 | fi 71 | shift 72 | done 73 | 74 | if [ ${stderr} != "0" ]; then 75 | exit 1 76 | fi 77 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.4 Ensure all users' home directories exist (Automated) 4 | # 5 | # Description: 6 | # Users can be defined in /etc/passwd without a home directory or with a home 7 | # directory that does not actually exist. 8 | # 9 | # Rationale: 10 | # f the user's home directory does not exist or is unassigned, the user will be 11 | # placed in "/" and will not be able to write any files or have local environment 12 | # variables set. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare dir="" 18 | declare line="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d "$dir" ]; then 36 | echo "The home directory ($dir) of user ${user} does not exist." 37 | stderr="1" 38 | fi 39 | fi 40 | 41 | done < /etc/passwd 42 | 43 | if [ ${stderr} != "0" ]; then 44 | exit 1 45 | fi 46 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.5 Ensure users' home directories permissions are 750 or more restrictive (Automated) 4 | # 5 | # Description: 6 | # While the system administrator can establish secure permissions 7 | # for users' home directories, the users can easily override these. 8 | # 9 | # Rationale: 10 | # Group or world-writable user home directories may enable malicious users to 11 | # steal or modify other users' data or to gain another user's system privileges. 12 | 13 | set -o errexit 14 | set -o nounset 15 | 16 | declare dir="" 17 | declare dirperm="" 18 | declare line="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d ${dir} ]; then 36 | echo "The home directory (${dir}) of user ${user} does not exist." 37 | stderr="1" 38 | else 39 | dirperm=$(ls -ld $dir | cut -f1 -d" ") || status=1 40 | if [ ${status} = "0" ]; then 41 | if [ $(echo ${dirperm} | cut -c6) != "-" ]; then 42 | echo "Group Write permission set on the home directory (${dir}) of user ${user}" 43 | stderr="1" 44 | fi 45 | if [ $(echo ${dirperm} | cut -c8) != "-" ]; then 46 | echo "Other Read permission set on the home directory (${dir}) of user ${user}" 47 | stderr="1" 48 | fi 49 | if [ $(echo ${dirperm} | cut -c9) != "-" ]; then 50 | echo "Other Write permission set on the home directory (${dir}) of user ${user}" 51 | stderr="1" 52 | fi 53 | if [ $(echo ${dirperm} | cut -c10) != "-" ]; then 54 | echo "Other Execute permission set on the home directory (${dir}) of user ${user}" 55 | stderr="1" 56 | fi 57 | fi 58 | fi 59 | fi 60 | 61 | done < /etc/passwd 62 | 63 | if [ ${stderr} != "0" ]; then 64 | exit 1 65 | fi 66 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.6 Ensure users own their home directories (Automated) 4 | # 5 | # Description: 6 | # The user home directory is space defined for the particular user to set local 7 | # environment variables and to store personal files. 8 | # 9 | # Rationale: 10 | # Since the user is accountable for files stored in the user home directory, the 11 | # user must be the owner of the directory. 12 | 13 | set -o errexit 14 | set -o nounset 15 | 16 | declare dir="" 17 | declare line="" 18 | declare owner="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d "$dir" ]; then 36 | echo "The home directory ($dir) of user ${user} does not exist." 37 | stderr="1" 38 | else 39 | owner=$(stat -L -c "%U" "${dir}") || status=1 40 | if [ ${status} = "0" ]; then 41 | if [ "${owner}" != "${user}" ]; then 42 | echo "The home directory (${dir}) of user ${user} is owned by ${owner}." 43 | stderr="1" 44 | fi 45 | fi 46 | fi 47 | fi 48 | 49 | done < /etc/passwd 50 | 51 | if [ ${stderr} != "0" ]; then 52 | exit 1 53 | fi 54 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.7 Ensure users' dot files are not group or world writable (Automated) 4 | # 5 | # Description: 6 | # While the system administrator can establish secure permissions for users' 7 | # "dot" files, the users can easily override these. 8 | # 9 | # Group or world-writable user configuration files may enable malicious users to 10 | # steal or modify other users' data or to gain another user's system privileges. 11 | 12 | set -o errexit 13 | set -o nounset 14 | 15 | declare dir="" 16 | declare file="" 17 | declare fileperm="" 18 | declare line="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d "$dir" ]; then 36 | echo "The home directory (${dir}) of user ${user} does not exist." 37 | stderr="1" 38 | else 39 | for file in ${dir}/.[A-Za-z0-9]*; do 40 | if [ ! -h "${file}" -a -f "${file}" ]; then 41 | fileperm=`ls -ld ${file} | cut -f1 -d" "` 42 | if [ $(echo ${fileperm} | cut -c6) != "-" ]; then 43 | echo "Group Write permission set on file ${file}" 44 | stderr="1" 45 | fi 46 | if [ $(echo ${fileperm} | cut -c9) != "-" ]; then 47 | echo "Other Write permission set on file ${file}" 48 | stderr="1" 49 | fi 50 | fi 51 | done 52 | fi 53 | fi 54 | 55 | done < /etc/passwd 56 | 57 | if [ ${stderr} != "0" ]; then 58 | exit 1 59 | fi 60 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.8 Ensure no users have .forward files (Automated) 4 | # 5 | # Description: 6 | # The .forward file specifies an email address to forward the user's mail to. 7 | # 8 | # Rationale: 9 | # Use of the .forward file poses a security risk in that sensitive data may be 10 | # inadvertently transferred outside the organization. The .forward file also 11 | # poses a risk as it can be used to execute commands that may perform unintended 12 | # actions. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare dir="" 18 | declare line="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d ${dir} ]; then 36 | echo "The home directory (${dir}) of user ${user} does not exist." 37 | stderr="1" 38 | else 39 | if [ ! -h "${dir}/.forward" -a -f "${dir}/.forward" ]; then 40 | echo ".forward file ${dir}/.forward exists" 41 | stderr="1" 42 | fi 43 | fi 44 | fi 45 | 46 | done < /etc/passwd 47 | 48 | if [ ${stderr} != "0" ]; then 49 | exit 1 50 | fi 51 | -------------------------------------------------------------------------------- /scripts/test_section_06_level1/6-2-9.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 6.2.9 Ensure no users have .netrc files (Automated) 4 | # 5 | # Description: 6 | # The .netrc file contains data for logging into a remote host for 7 | # file transfers via FTP. 8 | # 9 | # Rationale: 10 | # The .netrc file presents a significant security risk since it stores passwords 11 | # in unencrypted form. Even if FTP is disabled, user accounts may have brought 12 | # over .netrc files from other systems which could pose a risk to those systems. 13 | 14 | set -o errexit 15 | set -o nounset 16 | 17 | declare dir="" 18 | declare line="" 19 | declare status="0" 20 | declare stderr="0" 21 | declare user="" 22 | declare vars="" 23 | 24 | while read line; do 25 | 26 | vars=$( 27 | echo ${line} | \ 28 | egrep -v '^(root|halt|sync|shutdown)' | \ 29 | awk -F: '($7 != "/usr/sbin/nologin" && $7 != "/bin/false") { print $1 " " $6 }' 30 | ) || status=1 31 | 32 | if [ ${status} = "0" -a "${vars}x" != "x" ]; then 33 | set -- ${vars} 34 | user=${1-} && dir=${2-} 35 | if [ ! -d ${dir} ]; then 36 | echo "The home directory (${dir}) of user ${user} does not exist." 37 | stderr="1" 38 | else 39 | if [ ! -h "${dir}/.netrc" -a -f "${dir}/.netrc" ]; then 40 | echo ".netrc file ${dir}/.netrc exists" 41 | stderr="1" 42 | fi 43 | fi 44 | fi 45 | 46 | done < /etc/passwd 47 | 48 | if [ ${stderr} != "0" ]; then 49 | exit 1 50 | fi 51 | -------------------------------------------------------------------------------- /test_section_01_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # CIS Ubuntu Linux 20.04 LTS Benchmark v1.0.0 3 | # 4 | # 1 Initial Setup 5 | # 1.2.1 Ensure package manager repositories are configured (Manual): not implemented 6 | # 1.2.2 Ensure GPG keys are configured (Manual): not implemented 7 | # 1.3.2 Ensure sudo commands use pty (Automated): not implemented 8 | # 1.4 Filesystem Integrity Checking 9 | # 1.4.1 Ensure AIDE is installed (Automated) : not implemented 10 | # 1.4.2 Ensure filesystem integrity is regularly checked (Automated): not implemented 11 | # 1.5 Secure Boot Settings 12 | # 1.5.1 Ensure bootloader password is set (Automated): not implemented 13 | # 1.5.3 Ensure authentication required for single user mode (Automated): not implemented 14 | 15 | command: 16 | # 1.1 Filesystem Configuration 17 | # 1.1.1 Disable unused filesystems 18 | # 1.1.1.1 Ensure mounting of cramfs filesystems is disabled (Automated) 19 | modprobe -n -v cramfs: 20 | exit-status: 0 21 | stdout: 22 | - "install /bin/false" 23 | lsmod | grep cramfs: 24 | exit-status: 1 25 | 26 | # 1.1.1.2 Ensure mounting of freevxfs filesystems is disabled (Automated) 27 | modprobe -n -v freevxfs: 28 | exit-status: 0 29 | stdout: 30 | - "install /bin/false" 31 | lsmod | grep freevxfs: 32 | exit-status: 1 33 | 34 | # 1.1.1.3 Ensure mounting of jffs2 filesystems is disabled (Automated) 35 | modprobe -n -v jffs2: 36 | exit-status: 0 37 | stdout: 38 | - "install /bin/false" 39 | lsmod | grep jffs2: 40 | exit-status: 1 41 | 42 | # 1.1.1.4 Ensure mounting of hfs filesystems is disabled (Automated) 43 | modprobe -n -v hfs: 44 | exit-status: 0 45 | stdout: 46 | - "install /bin/false" 47 | lsmod | grep hfs: 48 | exit-status: 1 49 | 50 | # 1.1.1.5 Ensure mounting of hfsplus filesystems is disabled (Automated) 51 | modprobe -n -v hfsplus: 52 | exit-status: 0 53 | stdout: 54 | - "install /bin/false" 55 | lsmod | grep hfsplus: 56 | exit-status: 1 57 | 58 | # 1.1.1.6 Ensure mounting of udf filesystems is disabled (Automated) 59 | modprobe -n -v udf | grep -E '(udf|install)': 60 | exit-status: 0 61 | stdout: 62 | - "install /bin/true" 63 | lsmod | grep udf: 64 | exit-status: 1 65 | 66 | # 1.1.2 Ensure /tmp is configured (Automated) 67 | systemctl is-enabled tmp.mount: 68 | exit-status: 0 69 | stdout: 70 | - "enabled" 71 | 72 | # 1.1.3 Ensure nodev option set on /tmp partition (Automated) 73 | mount | grep -E '\s/tmp\s' | grep -v nodev: 74 | exit-status: 1 75 | 76 | # 1.1.4 Ensure nosuid option set on /tmp partition (Automated) 77 | mount | grep -E '\s/tmp\s' | grep -v nosuid: 78 | exit-status: 1 79 | 80 | # 1.1.5 Ensure noexec option set on /tmp partition (Automated) 81 | mount | grep -E '\s/tmp\s' | grep -v noexec: 82 | exit-status: 1 83 | 84 | # 1.1.6 Ensure /dev/shm is configured (Automated) 85 | mount | grep -E '\s/dev/shm\s': 86 | exit-status: 1 87 | 88 | # 1.1.7 Ensure nodev option set on /dev/shm partition (Automated) 89 | mount | grep -E '\s/dev/shm\s' | grep -v nodev: 90 | exit-status: 1 91 | 92 | # 1.1.8 Ensure nosuid option set on /dev/shm partition (Automated) 93 | mount | grep -E '\s/dev/shm\s' | grep -v nosuid: 94 | exit-status: 1 95 | 96 | # 1.1.9 Ensure noexec option set on /dev/shm partition (Automated) 97 | mount | grep -E '\s/dev/shm\s' | grep -v noexec: 98 | exit-status: 1 99 | 100 | # 1.1.22 Ensure sticky bit is set on all world-writable directories (Automated) 101 | df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null: 102 | exit-status: 0 103 | stdout: [] 104 | timeout: 1000000 105 | 106 | # 1.1.23 Disable Automounting (Automated) 107 | systemctl is-enabled autofs: 108 | exit-status: 1 109 | 110 | # 1.1.24 Disable USB Storage (Automated) 111 | modprobe -n -v usb-storage: 112 | exit-status: 0 113 | stdout: 114 | - "install /bin/true" 115 | lsmod | grep usb-storage: 116 | exit-status: 1 117 | 118 | # 1.2 Configure Software Updates 119 | 120 | # 1.3 Configure sudo 121 | # 1.3.1 Ensure sudo is installed (Automated) 122 | dpkg -s sudo: 123 | exit-status: 0 124 | 125 | # 1.3.3 Ensure sudo log file exists (Automated) 126 | grep -Ei '^\s*Defaults\s+logfile=\S+' /etc/sudoers /etc/sudoers.d/*: 127 | exit-status: 0 128 | stdout: 129 | - 'Defaults logfile="/var/log/sudo.log"' 130 | 131 | # 1.5.2 Ensure permissions on bootloader config are configured (Automated) 132 | stat -c "%a-%u-%g-%U-%G" /boot/grub/grub.cfg: 133 | exit-status: 0 134 | stdout: 135 | - "400-0-0-root-root" 136 | 137 | # 1.6 Additional Process Hardening 138 | # 1.6.1 Ensure XD/NX support is enabled (Automated) 139 | journalctl -k | egrep "NX.*protection:.*active": 140 | exit-status: 0 141 | 142 | # 1.6.2 Ensure address space layout randomization (ASLR) is enabled (Automated) 143 | sysctl kernel.randomize_va_space: 144 | exit-status: 0 145 | stdout: 146 | - "kernel.randomize_va_space = 2" 147 | 148 | # 1.6.3 Ensure prelink is disabled (Automated) 149 | dpkg -s prelink: 150 | exit-status: 1 151 | 152 | # 1.6.4 Ensure core dumps are restricted (Automated) 153 | grep -E '^(\*|\s).*hard.*core.*(\s+#.*)?$' /etc/security/limits.conf /etc/security/limits.d/* 2>/dev/null: 154 | exit-status: 0 155 | stdout: 156 | - "* hard core 0" 157 | sysctl fs.suid_dumpable: 158 | exit-status: 0 159 | stdout: 160 | - "fs.suid_dumpable = 0" 161 | grep "fs.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/*: 162 | exit-status: 0 163 | stdout: 164 | - "fs.suid_dumpable = 0" 165 | 166 | 167 | # 1.7 Mandatory Access Control 168 | # 1.7.1 Configure AppArmor 169 | dpkg -s apparmor | grep Status: 170 | exit-status: 0 171 | stdout: 172 | - "Status: install ok installed" 173 | 174 | # 1.7.1.2 Ensure AppArmor is enabled in the bootloader configuration 175 | grep "^\s*linux" /boot/grub/grub.cfg | grep -v "apparmor=1": 176 | exit-status: 1 177 | stdout: [] 178 | grep "^\s*linux" /boot/grub/grub.cfg | grep -v "security=apparmor": 179 | exit-status: 1 180 | stdout: [] 181 | 182 | # 1.7.1.3 Ensure all AppArmor Profiles are in enforce or complain mode 183 | test $(expr `apparmor_status --enforced` + `apparmor_status --complaining`) = $(apparmor_status --profiled): 184 | exit-status: 0 185 | 186 | # 1.7.1.4 Ensure all AppArmor Profiles are enforcing (Automated): level 2 187 | 188 | # 1.9 Ensure updates, patches, and additional security software are installed (Manual) 189 | /usr/lib/update-notifier/apt-check: 190 | exit-status: 0 191 | stdout: 192 | - "" 193 | 194 | # 1.10 Ensure GDM is removed or login is configured (Automated) 195 | dpkg -s gdm3: 196 | exit-status: 1 197 | 198 | file: 199 | # 1.8 Warning Banners 200 | # 1.8.1 Command Line Warning Banners 201 | # 1.8.1.1 Ensure message of the day is configured properly (Automated) 202 | # 1.8.1.4 Ensure permissions on /etc/motd are configured (Automated) 203 | /etc/motd: 204 | exists: true 205 | mode: "0644" 206 | owner: root 207 | group: root 208 | contains: 209 | - "Authorized uses only. All activity may be monitored and reported." 210 | 211 | # 1.8.1.2 Ensure local login warning banner is configured properly (Automated) 212 | # 1.8.1.5 Ensure permissions on /etc/issue are configured (Automated) 213 | /etc/issue: 214 | exists: true 215 | mode: "0644" 216 | owner: root 217 | group: root 218 | contains: 219 | - "Authorized uses only. All activity may be monitored and reported." 220 | 221 | # 1.8.1.3 Ensure remote login warning banner is configured properly (Automated) 222 | # 1.8.1.6 Ensure permissions on /etc/issue.net are configured (Automated) 223 | /etc/issue.net: 224 | exists: true 225 | mode: "0644" 226 | owner: root 227 | group: root 228 | contains: 229 | - "Authorized uses only. All activity may be monitored and reported." 230 | -------------------------------------------------------------------------------- /test_section_02_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # CIS Ubuntu Linux 20.04 LTS Benchmark v1.0.0 3 | # 4 | # 2 Services 5 | # 2.2.1.2 Ensure systemd-timesyncd is configured (Manual): not implemented 6 | # 2.2.1.4 Ensure ntp is configured (Automated): not implemented 7 | # 2.4 Ensure nonessential services are removed or masked (Manual): not implemented 8 | 9 | command: 10 | # 2.2 Special Purpose Services 11 | # 2.2.1 Time Synchronization 12 | # 2.2.1.1 Ensure time synchronization is in use (Automated) 13 | dpkg -s chrony: 14 | exit-status: 0 15 | systemctl is-enabled chrony: 16 | exit-status: 0 17 | stdout: 18 | - "enabled" 19 | 20 | # 2.2.1.3 Ensure chrony is configured (Automated) 21 | grep -E "^(server|pool)" /etc/chrony/chrony.conf: 22 | exit-status: 0 23 | stdout: 24 | - "server metadata.google.internal iburst" 25 | 26 | # 2.2.15 Ensure mail transfer agent is configured for local-only mode (Automated) 27 | ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|::1):25\s': 28 | exit-status: 1 29 | stdout: [] 30 | 31 | package: 32 | # 2.1 inetd Services 33 | # 2.1.1 Ensure xinetd is not installed (Automated) 34 | xinetd: 35 | installed: false 36 | 37 | # 2.1.2 Ensure openbsd-inetd is not installed (Automated) 38 | openbsd-inetd: 39 | installed: false 40 | 41 | # 2.2.2 Ensure X Window System is not installed (Automated) 42 | xserver-xorg*: 43 | installed: false 44 | 45 | # 2.2.3 Ensure Avahi Server is not installed (Automated) 46 | avahi-daemon: 47 | installed: false 48 | 49 | # 2.2.4 Ensure CUPS is not installed (Automated) 50 | cups: 51 | installed: false 52 | 53 | # 2.2.5 Ensure DHCP Server is not installed (Automated) 54 | isc-dhcp-server: 55 | installed: false 56 | 57 | # 2.2.6 Ensure LDAP server is not installed (Automated) 58 | slapd: 59 | installed: false 60 | 61 | # 2.2.7 Ensure NFS is not installed (Automated) 62 | nfs-kernel-server: 63 | installed: false 64 | 65 | # 2.2.8 Ensure DNS Server is not installed (Automated) 66 | bind9: 67 | installed: false 68 | 69 | # 2.2.9 Ensure FTP Server is not installed (Automated) 70 | vsftpd: 71 | installed: false 72 | 73 | # 2.2.10 Ensure HTTP server is not installed (Automated) 74 | apache2: 75 | installed: false 76 | 77 | # 2.2.11 Ensure IMAP and POP3 server are not installed (Automated) 78 | dovecot-imapd: 79 | installed: false 80 | dovecot-pop3d: 81 | installed: false 82 | 83 | # 2.2.12 Ensure Samba is not installed (Automated) 84 | samba: 85 | installed: false 86 | 87 | # 2.2.13 Ensure HTTP Proxy Server is not installed (Automated) 88 | squid: 89 | installed: false 90 | 91 | # 2.2.14 Ensure SNMP Server is not installed (Automated) 92 | snmpd: 93 | installed: false 94 | 95 | # 2.2.16 Ensure rsync service is not installed (Automated) 96 | rsync: 97 | installed: false 98 | 99 | # 2.2.17 Ensure NIS Server is not installed (Automated) 100 | # 2.3 Service Clients 101 | # 2.3.1 Ensure NIS Client is not installed (Automated) 102 | nis: 103 | installed: false 104 | 105 | # 2.3.2 Ensure rsh client is not installed (Automated) 106 | rsh-client: 107 | installed: false 108 | 109 | # 2.3.3 Ensure talk client is not installed (Automated) 110 | talk: 111 | installed: false 112 | 113 | # 2.3.4 Ensure telnet client is not installed (Automated) 114 | telnet: 115 | installed: false 116 | 117 | # 2.3.5 Ensure LDAP client is not installed (Automated) 118 | ldap-utils: 119 | installed: false 120 | 121 | # 2.3.6 Ensure RPC is not installed (Automated) 122 | rpcbind: 123 | installed: false 124 | -------------------------------------------------------------------------------- /test_section_03_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # CIS Ubuntu Linux 20.04 LTS Benchmark v1.0.0 3 | # 4 | # 3 Network Configuration 5 | # 3.4 Uncommon Network Protocols: level 2 6 | # 3.4.1 Ensure DCCP is disabled (Automated): level 2 7 | # 3.4.2 Ensure SCTP is disabled (Automated): level 2 8 | # 3.4.3 Ensure RDS is disabled (Automated: level 2 9 | # 3.4.4 Ensure TIPC is disabled (Automated): level 2 10 | # 3.5 Firewall Configuration 11 | # 3.5.1 Configure Uncomplicated Firewall 12 | # 3.5.1.1 Ensure Uncomplicated Firewall is installed (Automated): not implemented 13 | # 3.5.1.2 Ensure iptables-persistent is not installed (Automated): not implemented 14 | # 3.5.1.3 Ensure ufw service is enabled (Automated): not implemented 15 | # 3.5.1.4 Ensure loopback traffic is configured (Automated): not implemented 16 | # 3.5.1.5 Ensure outbound connections are configured (Manual): not implemented 17 | # 3.5.1.6 Ensure firewall rules exist for all open ports (Manual): not implemented 18 | # 3.5.1.7 Ensure default deny firewall policy (Automated): not implemented 19 | # 3.5.2 Configure nftables 20 | # 3.5.2.1 Ensure nftables is installed (Automated): not implemented 21 | # 3.5.2.2 Ensure Uncomplicated Firewall is not installed or disabled (Automated): not implemented 22 | # 3.5.2.3 Ensure iptables are flushed (Manual): not implemented 23 | # 3.5.2.4 Ensure a table exists (Automated): not implemented 24 | # 3.5.2.5 Ensure base chains exist (Automated): not implemented 25 | # 3.5.2.6 Ensure loopback traffic is configured (Automated): not implemented 26 | # 3.5.2.7 Ensure outbound and established connections are configured (Manual): not implemented 27 | # 3.5.2.8 Ensure default deny firewall policy (Automated): not implemented 28 | # 3.5.2.9 Ensure nftables service is enabled (Automated): not implemented 29 | # 3.5.2.10 Ensure nftables rules are permanent (Automated): not implemented 30 | # 3.5.3 Configure iptables 31 | # 3.5.3.1 Configure software 32 | # 3.5.3.1.1 Ensure iptables packages are installed (Automated): not implemented 33 | # 3.5.3.1.2 Ensure nftables is not installed (Automated): not implemented 34 | # 3.5.3.1.3 Ensure Uncomplicated Firewall is not installed or disabled (Automated): not implemented 35 | # 3.5.3.2 Configure IPv4 iptables 36 | # 3.5.3.2.1 Ensure default deny firewall policy (Automated): not implemented 37 | # 3.5.3.2.2 Ensure loopback traffic is configured (Automated): not implemented 38 | # 3.5.3.2.4 Ensure firewall rules exist for all open ports (Automated): not implemented 39 | # 3.5.3.3 Configure IPv6 ip6tables 40 | # 3.5.3.3.1 Ensure IPv6 default deny firewall policy (Automated): not implemented 41 | # 3.5.3.3.2 Ensure IPv6 loopback traffic is configured (Automated): not implemented 42 | # 3.5.3.3.3 Ensure IPv6 outbound and established connections are configured (Manual): not implemented 43 | # 3.5.3.3.4 Ensure IPv6 firewall rules exist for all open ports (Manual): not implemented 44 | 45 | command: 46 | # 3.1 Disable unused network protocols and devices 47 | # 3.1.1 Disable IPv6 (Manual) 48 | grep "^\s*linux" /boot/grub/grub.cfg | grep -v "ipv6.disable=1": 49 | exit-status: 1 50 | stdout: [] 51 | 52 | # 3.1.2 Ensure wireless interfaces are disabled (Automated) 53 | bash /tmp/test_section_03_level1/3-1-2.sh: 54 | exit-status: 0 55 | stderr: [] 56 | stdout: 57 | - "Wireless is not enabled" 58 | timeout: 10000 59 | 60 | # 3.2 Network Parameters (Host Only) 61 | # 3.2.1 Ensure packet redirect sending is disabled (Automated) 62 | sysctl net.ipv4.conf.all.send_redirects: 63 | exit-status: 0 64 | stdout: 65 | - "net.ipv4.conf.all.send_redirects = 0" 66 | stderr: [] 67 | timeout: 10000 68 | sysctl net.ipv4.conf.default.send_redirects: 69 | exit-status: 0 70 | stdout: 71 | - "net.ipv4.conf.default.send_redirects = 0" 72 | stderr: [] 73 | timeout: 10000 74 | grep "^net\.ipv4\.conf\.all\.send_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 75 | exit-status: 0 76 | timeout: 10000 77 | grep "^net\.ipv4\.conf\.default\.send_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 78 | exit-status: 0 79 | timeout: 10000 80 | 81 | # 3.2.2 Ensure IP forwarding is disabled (Automated) 82 | sysctl net.ipv4.ip_forward: 83 | exit-status: 0 84 | stdout: 85 | - "net.ipv4.ip_forward = 0" 86 | stderr: [] 87 | timeout: 10000 88 | sysctl net.ipv6.conf.all.forwarding: 89 | exit-status: 0 90 | stdout: 91 | - "net.ipv6.conf.all.forwarding = 0" 92 | stderr: [] 93 | timeout: 10000 94 | 95 | # 3.3 Network Parameters (Host and Router) 96 | # 3.3.1 Ensure source routed packets are not accepted (Automated) 97 | sysctl net.ipv4.conf.all.accept_source_route: 98 | exit-status: 0 99 | stdout: 100 | - "net.ipv4.conf.all.accept_source_route = 0" 101 | stderr: [] 102 | timeout: 10000 103 | sysctl net.ipv4.conf.default.accept_source_route: 104 | exit-status: 0 105 | stdout: 106 | - "net.ipv4.conf.default.accept_source_route = 0" 107 | stderr: [] 108 | timeout: 10000 109 | grep "^net\.ipv4\.conf\.all\.accept_source_route=0" /etc/sysctl.conf /etc/sysctl.d/*: 110 | exit-status: 0 111 | timeout: 10000 112 | grep "^net\.ipv4\.conf\.default\.accept_source_route=0" /etc/sysctl.conf /etc/sysctl.d/*: 113 | exit-status: 0 114 | timeout: 10000 115 | sysctl net.ipv6.conf.all.accept_source_route: 116 | exit-status: 0 117 | stdout: 118 | - "net.ipv6.conf.all.accept_source_route = 0" 119 | stderr: [] 120 | timeout: 10000 121 | sysctl net.ipv6.conf.default.accept_source_route: 122 | exit-status: 0 123 | stdout: 124 | - "net.ipv6.conf.default.accept_source_route = 0" 125 | stderr: [] 126 | timeout: 10000 127 | 128 | # 3.3.2 Ensure ICMP redirects are not accepted (Automated) 129 | sysctl net.ipv4.conf.all.accept_redirects: 130 | exit-status: 0 131 | stdout: 132 | - "net.ipv4.conf.all.accept_redirects = 0" 133 | stderr: [] 134 | timeout: 10000 135 | sysctl net.ipv4.conf.default.accept_redirects: 136 | exit-status: 0 137 | stdout: 138 | - "net.ipv4.conf.default.accept_redirects = 0" 139 | stderr: [] 140 | timeout: 10000 141 | grep "^net\.ipv4\.conf\.all\.accept_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 142 | exit-status: 0 143 | timeout: 10000 144 | grep "^net\.ipv4\.conf\.default\.accept_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 145 | exit-status: 0 146 | timeout: 10000 147 | sysctl net.ipv6.conf.all.accept_redirects: 148 | exit-status: 0 149 | stdout: 150 | - "net.ipv6.conf.all.accept_redirects = 0" 151 | stderr: [] 152 | timeout: 10000 153 | sysctl net.ipv6.conf.default.accept_redirects: 154 | exit-status: 0 155 | stdout: 156 | - "net.ipv6.conf.default.accept_redirects = 0" 157 | stderr: [] 158 | timeout: 10000 159 | 160 | # 3.3.3 Ensure secure ICMP redirects are not accepted (Automated) 161 | sysctl net.ipv4.conf.all.secure_redirects: 162 | exit-status: 0 163 | stdout: 164 | - "net.ipv4.conf.all.secure_redirects = 0" 165 | stderr: [] 166 | timeout: 10000 167 | sysctl net.ipv4.conf.default.secure_redirects: 168 | exit-status: 0 169 | stdout: 170 | - "net.ipv4.conf.default.secure_redirects = 0" 171 | stderr: [] 172 | timeout: 10000 173 | grep "^net\.ipv4\.conf\.all\.secure_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 174 | exit-status: 0 175 | timeout: 10000 176 | grep "^net\.ipv4\.conf\.default\.secure_redirects=0" /etc/sysctl.conf /etc/sysctl.d/*: 177 | exit-status: 0 178 | timeout: 10000 179 | 180 | # 3.3.4 Ensure suspicious packets are logged (Automated) 181 | sysctl net.ipv4.conf.all.log_martians: 182 | exit-status: 0 183 | stdout: 184 | - "net.ipv4.conf.all.log_martians = 1" 185 | stderr: [] 186 | timeout: 10000 187 | sysctl net.ipv4.conf.default.log_martians: 188 | exit-status: 0 189 | stdout: 190 | - "net.ipv4.conf.default.log_martians = 1" 191 | stderr: [] 192 | timeout: 10000 193 | grep "^net\.ipv4\.conf\.all\.log_martians=1" /etc/sysctl.conf /etc/sysctl.d/*: 194 | exit-status: 0 195 | timeout: 10000 196 | grep "^net\.ipv4\.conf\.default\.log_martians=1" /etc/sysctl.conf /etc/sysctl.d/*: 197 | exit-status: 0 198 | timeout: 10000 199 | 200 | # 3.3.5 Ensure broadcast ICMP requests are ignored (Automated) 201 | sysctl net.ipv4.icmp_echo_ignore_broadcasts: 202 | exit-status: 0 203 | stdout: 204 | - "net.ipv4.icmp_echo_ignore_broadcasts = 1" 205 | stderr: [] 206 | timeout: 10000 207 | grep "^net\.ipv4\.icmp_echo_ignore_broadcasts=1" /etc/sysctl.conf /etc/sysctl.d/*: 208 | exit-status: 0 209 | timeout: 10000 210 | 211 | # 3.3.6 Ensure bogus ICMP responses are ignored (Automated) 212 | sysctl net.ipv4.icmp_ignore_bogus_error_responses: 213 | exit-status: 0 214 | stdout: 215 | - "net.ipv4.icmp_ignore_bogus_error_responses = 1" 216 | stderr: [] 217 | timeout: 10000 218 | grep "^net.ipv4.icmp_ignore_bogus_error_responses=1" /etc/sysctl.conf /etc/sysctl.d/*: 219 | exit-status: 0 220 | timeout: 10000 221 | 222 | # 3.3.7 Ensure Reverse Path Filtering is enabled (Automated) 223 | sysctl net.ipv4.conf.all.rp_filter: 224 | exit-status: 0 225 | stdout: 226 | - "net.ipv4.conf.all.rp_filter = 1" 227 | stderr: [] 228 | timeout: 10000 229 | sysctl net.ipv4.conf.default.rp_filter: 230 | exit-status: 0 231 | stdout: 232 | - "net.ipv4.conf.default.rp_filter = 1" 233 | stderr: [] 234 | timeout: 10000 235 | grep "^net\.ipv4\.conf\.all\.rp_filter=1" /etc/sysctl.conf /etc/sysctl.d/*: 236 | exit-status: 0 237 | timeout: 10000 238 | grep "^net\.ipv4\.conf\.default\.rp_filter=1" /etc/sysctl.conf /etc/sysctl.d/*: 239 | exit-status: 0 240 | timeout: 10000 241 | 242 | # 3.3.8 Ensure TCP SYN Cookies is enabled (Automated) 243 | sysctl net.ipv4.tcp_syncookies: 244 | exit-status: 0 245 | stdout: 246 | - "net.ipv4.tcp_syncookies = 1" 247 | stderr: [] 248 | timeout: 10000 249 | grep "^net\.ipv4\.tcp_syncookies=1" /etc/sysctl.conf /etc/sysctl.d/*: 250 | exit-status: 0 251 | timeout: 10000 252 | 253 | # 3.3.9 Ensure IPv6 router advertisements are not accepted (Automated) 254 | sysctl net.ipv6.conf.all.accept_ra: 255 | exit-status: 0 256 | stdout: 257 | - "net.ipv6.conf.all.accept_ra = 0" 258 | stderr: [] 259 | timeout: 10000 260 | sysctl net.ipv6.conf.default.accept_ra: 261 | exit-status: 0 262 | stdout: 263 | - "net.ipv6.conf.default.accept_ra = 0" 264 | stderr: [] 265 | timeout: 10000 266 | grep "^net\.ipv6\.conf\.all\.accept_ra=0" /etc/sysctl.conf /etc/sysctl.d/*: 267 | exit-status: 0 268 | timeout: 10000 269 | grep "^net\.ipv6\.conf\.default\.accept_ra=0" /etc/sysctl.conf /etc/sysctl.d/*: 270 | exit-status: 0 271 | timeout: 10000 272 | -------------------------------------------------------------------------------- /test_section_05_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # CIS Ubuntu Linux 20.04 LTS Benchmark v1.0.0 3 | # 4 | # 5 Access, Authentication and Authorization 5 | # 5.1 Configure time-based job schedulers 6 | # 5.3.2 Ensure lockout for failed password attempts is configured (Automated) : not implemented 7 | # 5.3.3 Ensure password reuse is limited (Automated): not implemented 8 | # 5.3.4 Ensure password hashing algorithm is SHA-512 (Automated): not implemented 9 | # 5.4.1.4 Ensure inactive password lock is 30 days or less (Automated): not implemented 10 | # 5.4.1.1 Ensure password expiration is 365 days or less (Automated): not implemented 11 | # 5.4.1.5 Ensure all users last password change date is in the past (Automated): not implemented 12 | # 5.4.2 Ensure system accounts are secured (Automated): not implemented 13 | # 5.4.5 Ensure default user shell timeout is 900 seconds or less (Automated): not implemented 14 | # 5.6 Ensure access to the su command is restricted (Automated): not implemented 15 | # 5.5 Ensure root login is restricted to system console (Manual): not implemented 16 | # 5.6 Ensure access to the su command is restricted (Automated): not implemented 17 | 18 | command: 19 | # 5.1.1 Ensure cron daemon is enabled and running (Automated) 20 | systemctl is-enabled cron: 21 | exit-status: 0 22 | stdout: 23 | - "enabled" 24 | systemctl status cron | grep "active (running) ": 25 | exit-status: 0 26 | 27 | # 5.2.2 Ensure permissions on SSH private host key files are configured (Automated) 28 | bash /tmp/test_section_05_level1/5-2-2.sh: 29 | exit-status: 0 30 | stdout: 31 | - "Ownership and permissions of private key are correct" 32 | stderr: [] 33 | timeout: 10000 34 | 35 | # 5.2.3 Ensure permissions on SSH public host key files are configured (Automated) 36 | bash /tmp/test_section_05_level1/5-2-3.sh: 37 | exit-status: 0 38 | stdout: 39 | - "Ownership and permissions of public key are correct" 40 | stderr: [] 41 | timeout: 10000 42 | 43 | # 5.4.3 Ensure default group for the root account is GID 0 (Automated) 44 | grep "^root:" /etc/passwd | cut -f4 -d: 45 | exit-status: 0 46 | stdout: 47 | - "0" 48 | 49 | # 5.4.4 Ensure default user umask is 027 or more restrictive (Automated) 50 | bash /tmp/test_section_05_level1/5-2-4.sh: 51 | exit-status: 0 52 | stdout: 53 | - "Default user umask is set" 54 | stderr: [] 55 | timeout: 10000 56 | 57 | file: 58 | # 5.1.2 Ensure permissions on /etc/crontab are configured (Automated) 59 | /etc/crontab: 60 | exists: true 61 | mode: "0600" 62 | owner: root 63 | group: root 64 | 65 | # 5.1.3 Ensure permissions on /etc/cron.hourly are configured (Automated) 66 | /etc/cron.hourly/: 67 | exists: true 68 | mode: "0700" 69 | owner: root 70 | group: root 71 | 72 | # 5.1.4 Ensure permissions on /etc/cron.daily are configured (Automated) 73 | /etc/cron.daily/: 74 | exists: true 75 | mode: "0700" 76 | owner: root 77 | group: root 78 | 79 | # 5.1.5 Ensure permissions on /etc/cron.weekly are configured (Automated) 80 | /etc/cron.weekly/: 81 | exists: true 82 | mode: "0700" 83 | owner: root 84 | group: root 85 | 86 | # 5.1.6 Ensure permissions on /etc/cron.monthly are configured (Automated) 87 | /etc/cron.monthly/: 88 | exists: true 89 | mode: "0700" 90 | owner: root 91 | group: root 92 | 93 | # 5.1.7 Ensure permissions on /etc/cron.d are configured (Automated) 94 | /etc/cron.d/: 95 | exists: true 96 | mode: "0700" 97 | owner: root 98 | group: root 99 | 100 | # 5.1.8 Ensure cron is restricted to authorized users (Automated) 101 | /etc/cron.allow: 102 | exists: true 103 | mode: "0700" 104 | owner: root 105 | group: root 106 | contains: 107 | - "root" 108 | 109 | # 5.1.9 Ensure at is restricted to authorized users (Automated) 110 | /etc/at.allow: 111 | exists: true 112 | mode: "0700" 113 | owner: root 114 | group: root 115 | contains: 116 | - "root" 117 | 118 | # 5.2 Configure SSH Server 119 | # 5.2.1 Ensure permissions on /etc/ssh/sshd_config are configured (Scored) 120 | # 5.2.4 Ensure SSH LogLevel is appropriate (Automated) 121 | # 5.2.5 Ensure SSH X11 forwarding is disabled (Automated) 122 | # 5.2.6 Ensure SSH MaxAuthTries is set to 4 or less (Automated) 123 | # 5.2.7 Ensure SSH IgnoreRhosts is enabled (Automated) 124 | # 5.2.8 Ensure SSH HostbasedAuthentication is disabled (Automated) 125 | # 5.2.9 Ensure SSH root login is disabled (Automated) 126 | # 5.2.10 Ensure SSH PermitEmptyPasswords is disabled (Automated) 127 | # 5.2.11 Ensure SSH PermitUserEnvironment is disabled (Automated) 128 | # 5.2.12 Ensure only strong Ciphers are used (Automated) 129 | # 5.2.13 Ensure only strong MAC algorithms are used (Automated) 130 | # 5.2.14 Ensure only strong Key Exchange algorithms are used (Automated) 131 | # 5.2.15 Ensure SSH Idle Timeout Interval is configured (Automated) 132 | # 5.2.16 Ensure SSH LoginGraceTime is set to one minute or less (Automated) 133 | # 5.2.17 Ensure SSH access is limited (Automated) 134 | # 5.2.19 Ensure SSH PAM is enabled (Automated) 135 | # 5.2.20 Ensure SSH AllowTcpForwarding is disabled (Automated) 136 | # 5.2.21 Ensure SSH MaxStartups is configured (Automated) 137 | # 5.2.22 Ensure SSH MaxSessions is limited (Automated) 138 | /etc/ssh/sshd_config: 139 | exists: true 140 | mode: "0600" 141 | owner: root 142 | group: root 143 | contains: 144 | - "Protocol 2" 145 | - "LogLevel INFO" 146 | - "X11Forwarding no" 147 | - "MaxAuthTries 2" 148 | - "IgnoreRhosts yes" 149 | - "HostbasedAuthentication no" 150 | - "PermitRootLogin no" 151 | - "PermitEmptyPasswords no" 152 | - "PermitUserEnvironment no" 153 | - "MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com" 154 | - "ClientAliveInterval 300" 155 | - "ClientAliveCountMax 0" 156 | - "LoginGraceTime 60" 157 | - "Banner /etc/issue.net" 158 | - "DenyUsers root" 159 | - "UsePAM yes" 160 | - "AllowTcpForwarding no" 161 | - "MaxStartups 10:30:100" 162 | - "MaxSessions 10" 163 | 164 | # 5.2.18 Ensure SSH warning banner is configured (Automated) 165 | /etc/issue.net: 166 | exists: true 167 | mode: "0644" 168 | owner: root 169 | group: root 170 | 171 | # 5.3.1 Ensure password creation requirements are configured (Automated) 172 | /etc/security/pwquality.conf: 173 | exists: true 174 | mode: "0644" 175 | owner: root 176 | group: root 177 | contains: 178 | - "minlen = 14" 179 | - "minclass = 4" 180 | /etc/pam.d/common-password: 181 | exists: true 182 | mode: "0644" 183 | owner: root 184 | group: root 185 | contains: 186 | - "pam_pwquality.so retry=3" 187 | 188 | # 5.4 User Accounts and Environment 189 | # 5.4.1 Set Shadow Password Suite Parameters 190 | # 5.4.1.1 Ensure password expiration is 365 days or less (Automated) 191 | # 5.4.1.2 Ensure minimum days between password changes is configured (Automated) 192 | # 5.4.1.3 Ensure password expiration warning days is 7 or more (Automated) 193 | /etc/login.defs: 194 | exists: true 195 | mode: "0644" 196 | owner: root 197 | group: root 198 | contains: 199 | - "PASS_MAX_DAYS 365" 200 | - "PASS_MIN_DAYS 1" 201 | - "PASS_WARN_AGE 7" 202 | -------------------------------------------------------------------------------- /test_section_06_level1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # CIS Ubuntu Linux 20.04 LTS Benchmark v1.0.0 3 | # 4 | # 6.1 System File Permissions 5 | 6 | file: 7 | # 6.1.2 Ensure permissions on /etc/passwd are configured (Automated) 8 | /etc/passwd: 9 | exists: true 10 | mode: "0644" 11 | owner: root 12 | group: root 13 | 14 | # 6.1.3 Ensure permissions on /etc/gshadow- are configured (Automated) 15 | /etc/gshadow-: 16 | exists: true 17 | mode: "0640" 18 | owner: root 19 | group: shadow 20 | 21 | # 6.1.4 Ensure permissions on /etc/shadow are configured (Automated) 22 | /etc/shadow: 23 | exists: true 24 | mode: "0640" 25 | owner: root 26 | group: shadow 27 | 28 | # 6.1.5 Ensure permissions on /etc/group are configured (Automated) 29 | /etc/group: 30 | exists: true 31 | mode: "0644" 32 | owner: root 33 | group: root 34 | 35 | # 6.1.6 Ensure permissions on /etc/passwd- are configured (Automated) 36 | /etc/passwd-: 37 | exists: true 38 | mode: "0644" 39 | owner: root 40 | group: root 41 | 42 | # 6.1.7 Ensure permissions on /etc/shadow- are configured (Automated) 43 | /etc/shadow-: 44 | exists: true 45 | mode: "0640" 46 | owner: root 47 | group: shadow 48 | 49 | # 6.1.8 Ensure permissions on /etc/group- are configured (Automated) 50 | /etc/group-: 51 | exists: true 52 | mode: "0644" 53 | owner: root 54 | group: root 55 | 56 | # 6.1.9 Ensure permissions on /etc/gshadow are configured (Automated) 57 | /etc/gshadow: 58 | exists: true 59 | mode: "0640" 60 | owner: root 61 | group: shadow 62 | 63 | command: 64 | # 6.1.10 Ensure no world writable files exist (Automated) 65 | df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type f -perm -0002: 66 | exit-status: 0 67 | stderr: [] 68 | stdout: [] 69 | timeout: 100000 70 | 71 | # 6.1.11 Ensure no unowned files or directories exist (Automated) 72 | df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nouser: 73 | exit-status: 0 74 | stderr: [] 75 | stdout: [] 76 | timeout: 100000 77 | 78 | # 6.1.12 Ensure no ungrouped files or directories exist (Automated) 79 | df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -nogroup: 80 | exit-status: 0 81 | stderr: [] 82 | stdout: [] 83 | timeout: 100000 84 | 85 | # 6.1.13 Audit SUID executables (Manual) 86 | bash /tmp/test_section_06_level1/6-1-13.sh: 87 | exit-status: 0 88 | stderr: [] 89 | timeout: 10000 90 | 91 | # 6.1.14 Audit SGID executables (Manual) 92 | bash /tmp/test_section_06_level1/6-1-14.sh: 93 | exit-status: 0 94 | stderr: [] 95 | timeout: 10000 96 | 97 | # 6.2 User and Group Settings 98 | # 6.2.1 Ensure password fields are not empty (Automated) 99 | awk -F':' '($2 == "" ) { print $1 " does not have a password "}' /etc/shadow: 100 | exit-status: 0 101 | stderr: [] 102 | timeout: 10000 103 | 104 | # 6.2.2 Ensure root is the only UID 0 account (Automated) 105 | awk -F':' '($3 == 0) { print $1 }' /etc/passwd: 106 | exit-status: 0 107 | stderr: [] 108 | stdout: 109 | - "root" 110 | timeout: 10000 111 | 112 | # 6.2.3 Ensure root PATH Integrity (Automated) 113 | bash /tmp/test_section_06_level1/6-2-3.sh: 114 | exit-status: 0 115 | stderr: [] 116 | timeout: 10000 117 | 118 | # 6.2.4 Ensure all users' home directories exist (Automated) 119 | bash /tmp/test_section_06_level1/6-2-4.sh: 120 | exit-status: 0 121 | stderr: [] 122 | timeout: 10000 123 | 124 | # 6.2.5 Ensure users' home directories permissions are 750 or more restrictive (Automated) 125 | bash /tmp/test_section_06_level1/6-2-5.sh: 126 | exit-status: 0 127 | stderr: [] 128 | timeout: 10000 129 | 130 | # 6.2.6 Ensure users own their home directories (Automated) 131 | bash /tmp/test_section_06_level1/6-2-6.sh: 132 | exit-status: 0 133 | stderr: [] 134 | timeout: 10000 135 | 136 | # 6.2.7 Ensure users' dot files are not group or world writable (Automated) 137 | bash /tmp/test_section_06_level1/6-2-7.sh: 138 | exit-status: 0 139 | stderr: [] 140 | timeout: 10000 141 | 142 | # 6.2.8 Ensure no users have .forward files (Automated) 143 | bash /tmp/test_section_06_level1/6-2-8.sh: 144 | exit-status: 0 145 | stderr: [] 146 | timeout: 10000 147 | 148 | # 6.2.9 Ensure no users have .netrc files (Automated) 149 | bash /tmp/test_section_06_level1/6-2-9.sh: 150 | exit-status: 0 151 | stderr: [] 152 | timeout: 10000 153 | 154 | # 6.2.10 Ensure users' .netrc Files are not group or world accessible (Automated) 155 | bash /tmp/test_section_06_level1/6-2-10.sh: 156 | exit-status: 0 157 | stderr: [] 158 | timeout: 10000 159 | 160 | # 6.2.11 Ensure no users have .rhosts files (Automated) 161 | bash /tmp/test_section_06_level1/6-2-11.sh: 162 | exit-status: 0 163 | stderr: [] 164 | timeout: 10000 165 | 166 | # 6.2.12 Ensure all groups in /etc/passwd exist in /etc/group (Automated) 167 | bash /tmp/test_section_06_level1/6-2-12.sh: 168 | exit-status: 0 169 | stderr: [] 170 | timeout: 10000 171 | 172 | # 6.2.13 Ensure no duplicate UIDs exist (Automated) 173 | bash /tmp/test_section_06_level1/6-2-13.sh: 174 | exit-status: 0 175 | stderr: [] 176 | timeout: 10000 177 | 178 | # 6.2.14 Ensure no duplicate GIDs exist (Automated) 179 | bash /tmp/test_section_06_level1/6-2-14.sh: 180 | exit-status: 0 181 | stderr: [] 182 | timeout: 10000 183 | 184 | # 6.2.15 Ensure no duplicate user names exist (Automated) 185 | bash /tmp/test_section_06_level1/6-2-15.sh: 186 | exit-status: 0 187 | stderr: [] 188 | timeout: 10000 189 | 190 | # 6.2.16 Ensure no duplicate group names exist (Automated) 191 | bash /tmp/test_section_06_level1/6-2-16.sh: 192 | exit-status: 0 193 | stderr: [] 194 | timeout: 10000 195 | 196 | # 6.2.17 Ensure shadow group is empty (Automated) 197 | grep ^shadow:[^:]*:[^:]*:[^:]+ /etc/group || exit 0: 198 | exit-status: 0 199 | stderr: [] 200 | stdout: [] 201 | timeout: 10000 202 | awk -F':' '($4 == "") { print }' /etc/passwd || exit 0: 203 | exit-status: 0 204 | stderr: [] 205 | stdout: [] 206 | timeout: 10000 207 | --------------------------------------------------------------------------------