/
usr
/
share
/
lynis
/
include
/
/usr/share/lynis/include
mkdir
upload
Name
Size
Mode
Actions
binaries
39476
0644
edit
dl
rm
consts
10898
0644
edit
dl
rm
data_upload
13788
0644
edit
dl
rm
functions
163241
0644
edit
dl
rm
helper_audit_dockerfile
8000
0644
edit
dl
rm
helper_configure
3748
0644
edit
dl
rm
helper_generate
7557
0644
edit
dl
rm
helper_show
22820
0644
edit
dl
rm
helper_system_remote_scan
3620
0644
edit
dl
rm
helper_update
3671
0644
edit
dl
rm
osdetection
48570
0644
edit
dl
rm
parameters
16874
0644
edit
dl
rm
profiles
27540
0644
edit
dl
rm
report
18915
0644
edit
dl
rm
tests_accounting
25852
0644
edit
dl
rm
tests_authentication
86063
0644
edit
dl
rm
tests_banners
8562
0644
edit
dl
rm
tests_boot_services
56034
0644
edit
dl
rm
tests_containers
11439
0644
edit
dl
rm
tests_crypto
19456
0644
edit
dl
rm
tests_custom.template
6942
0644
edit
dl
rm
tests_databases
24863
0644
edit
dl
rm
tests_dns
3467
0644
edit
dl
rm
tests_filesystems
50995
0644
edit
dl
rm
tests_file_integrity
22714
0644
edit
dl
rm
tests_file_permissions
3185
0644
edit
dl
rm
tests_firewalls
32270
0644
edit
dl
rm
tests_hardening
7187
0644
edit
dl
rm
tests_homedirs
9392
0644
edit
dl
rm
tests_insecure_services
27528
0644
edit
dl
rm
tests_kerberos
8063
0644
edit
dl
rm
tests_kernel
61403
0644
edit
dl
rm
tests_kernel_hardening
5752
0644
edit
dl
rm
tests_ldap
4055
0644
edit
dl
rm
tests_logging
33726
0644
edit
dl
rm
tests_mac_frameworks
15067
0644
edit
dl
rm
tests_mail_messaging
21967
0644
edit
dl
rm
tests_malware
21101
0644
edit
dl
rm
tests_memory_processes
7334
0644
edit
dl
rm
tests_nameservices
35361
0644
edit
dl
rm
tests_networking
41705
0644
edit
dl
rm
tests_php
29772
0644
edit
dl
rm
tests_ports_packages
83692
0644
edit
dl
rm
tests_printers_spoolers
14188
0644
edit
dl
rm
tests_scheduling
16131
0644
edit
dl
rm
tests_shells
13643
0644
edit
dl
rm
tests_snmp
4273
0644
edit
dl
rm
tests_squid
17156
0644
edit
dl
rm
tests_ssh
18026
0644
edit
dl
rm
tests_storage
3680
0644
edit
dl
rm
tests_storage_nfs
8603
0644
edit
dl
rm
tests_system_integrity
2098
0644
edit
dl
rm
tests_time
33413
0644
edit
dl
rm
tests_tooling
22624
0644
edit
dl
rm
tests_usb
21554
0644
edit
dl
rm
tests_virtualization
1992
0644
edit
dl
rm
tests_webservers
33977
0644
edit
dl
rm
tool_tips
2205
0644
edit
dl
rm
Edit:
/usr/share/lynis/include/tests_authentication
(86063B)
#!/bin/sh ################################################################################# # # Lynis # ------------------ # # Copyright (c) Michael Boelen, CISOfy, and many contributors. # # Website : https://cisofy.com # Blog : https://linux-audit.com/ # GitHub : https://github.com/CISOfy/lynis # # Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are # welcome to redistribute it under the terms of the GNU General Public License. # See LICENSE file for usage of this software. # ################################################################################# # # User, Group and authentication tests # ################################################################################# # LDAP_AUTH_ENABLED=0 LDAP_PAM_ENABLED=0 LDAP_CONF_LOCATIONS="${ROOTDIR}etc/ldap.conf ${ROOTDIR}etc/ldap/ldap.conf ${ROOTDIR}etc/openldap/ldap.conf ${ROOTDIR}usr/local/etc/ldap.conf ${ROOTDIR}usr/local/etc/openldap/ldap.conf" PAM_FILE_LOCATIONS="${ROOTDIR}usr/lib/aarch64-linux-gnu/security ${ROOTDIR}lib/arm-linux-gnueabihf/security ${ROOTDIR}lib/i386-linux-gnu/security ${ROOTDIR}lib/security ${ROOTDIR}lib/x86_64-linux-gnu/security ${ROOTDIR}lib/powerpc64le-linux-gnu/security ${ROOTDIR}lib64/security ${ROOTDIR}usr/lib /usr/lib/security" SUDOERS_LOCATIONS="${ROOTDIR}etc/sudoers ${ROOTDIR}usr/local/etc/sudoers ${ROOTDIR}usr/pkg/etc/sudoers" SUDOERS_FILE="" # ################################################################################# # InsertSection "${SECTION_USERS_GROUPS_AND_AUTHENTICATION}" # Test : AUTH-9204 # Description : Check users with UID zero (0) # Notes : Ignores :0: in file if match is in NIS related line Register --test-no AUTH-9204 --weight L --network NO --category security --description "Check users with an UID of zero" if [ ${SKIPTEST} -eq 0 ]; then # Search accounts with UID 0 LogText "Test: Searching accounts with UID 0" # Check if device is a QNAP, as the root user is called admin, and not root if [ ${QNAP_DEVICE} -eq 1 ]; then FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${GREPBINARY} -E -v '^#|^admin:|^(\+:\*)?:0:0:::' | ${CUTBINARY} -d ":" -f1,3 | ${GREPBINARY} ':0') else FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${GREPBINARY} -E -v '^#|^root:|^(\+:\*)?:0:0:::' | ${CUTBINARY} -d ":" -f1,3 | ${GREPBINARY} ':0') fi if [ -n "${FIND}" ]; then Display --indent 2 --text "- Administrator accounts" --result "${STATUS_WARNING}" --color RED LogText "Result: Found more than one administrator accounts" ReportWarning "${TEST_NO}" "Multiple users with UID 0 found in passwd file" for USER in ${FIND}; do LogText "Administrator account: ${USER}" Report "user_with_uid_zero[]=${USER}" if [ "${USER}" = "toor" ]; then LogText "BSD note: default there is a user 'toor' installed. This account is considered useless unless it" LogText "is assigned a password and used for daily operations or emergencies. ie: bad shell for root user." ReportSuggestion "${TEST_NO}" "Use vipw to delete the 'toor' user if not used." fi done else Display --indent 2 --text "- Administrator accounts" --result "${STATUS_OK}" --color GREEN LogText "Result: No accounts found with UID 0 other than root." fi fi # ################################################################################# # # Test : AUTH-9208 # Description : Check non-unique accounts Register --test-no AUTH-9208 --weight L --network NO --category security --description "Check non-unique accounts in passwd file" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking for non-unique accounts" if [ "${OS}" = "DragonFly" -o "${OS}" = "FreeBSD" -o "${OS}" = "NetBSD" -o "${OS}" = "OpenBSD" ]; then PASSWD_FILE="${ROOTDIR}etc/master.passwd" else PASSWD_FILE="${ROOTDIR}etc/passwd" fi # Check password file if [ -f ${PASSWD_FILE} ]; then FIND=$(${GREPBINARY} -v '^#' ${PASSWD_FILE} | ${CUTBINARY} -d ':' -f3 | ${SORTBINARY} | uniq -d) if [ "${FIND}" = "" ]; then Display --indent 2 --text "- Unique UIDs" --result "${STATUS_OK}" --color GREEN LogText "Result: all accounts found in ${PASSWD_FILE} are unique" else Display --indent 2 --text "- Unique UIDs" --result "${STATUS_WARNING}" --color RED LogText "Result: found multiple accounts with same UID" LogText "Output (non-unique UIDs): ${FIND}" ReportWarning "${TEST_NO}" "Multiple accounts found with same UID" fi else Display --indent 2 --text "- Unique UIDs" --result "${STATUS_SKIPPED}" --color WHITE LogText "Result: test skipped, ${PASSWD_FILE} file not available" fi LogText "Remarks: Non unique UIDs can be a risk for the system or part of a configuration mistake" fi # ################################################################################# # # Test : AUTH-9212 # Description : Test group file with chkgrp tool (ie FreeBSD) LogText "Prerequisite test: /usr/sbin/chkgrp" if [ -x ${ROOTDIR}usr/sbin/chkgrp ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9212 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Test group file" if [ ${SKIPTEST} -eq 0 ]; then Display --indent 2 --text "- Checking chkgrp tool" --result "${STATUS_FOUND}" --color GREEN LogText "Result: /usr/sbin/chkgrp binary found. Using this to perform next test(s)." LogText "Test: Testing consistency of /etc/group file" FIND=$(${ROOTDIR}usr/sbin/chkgrp | ${GREPBINARY} -v 'is fine') if [ "${FIND}" = "" ]; then Display --indent 4 --text "- Checking consistency of /etc/group file" --result "${STATUS_OK}" --color GREEN LogText "Result: chkgrp test performed, Group file seems to be ok." else Display --indent 4 --text "- Checking consistency of /etc/group file" --result "${STATUS_WARNING}" --color RED LogText "Result: chkgrp found some errors. Run the tool manually to see details." LogText "chkgrp output: ${FIND}" ReportWarning "${TEST_NO}" "chkgrp reported inconsistencies in /etc/group file" fi fi # ################################################################################# # # Test : AUTH-9216 # Description : Check /etc/group and shadow group files # Notes : Run grpck to test group files (most likely /etc/group and shadow group files) if [ -n "${GRPCKBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9216 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description "Check group and shadow group files" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking for grpck binary output" case ${OS} in "AIX") FIND=$(${GRPCKBINARY} -n ALL 2> /dev/null ; echo $?) ;; "Linux") if [ "${LINUX_VERSION}" = "SuSE" ]; then FIND=$(${GRPCKBINARY} -q -r > /dev/null ; echo $?) else FIND=$(${GRPCKBINARY} -r 2> /dev/null ; echo $?) fi ;; *) FIND=$(${GRPCKBINARY} 2> /dev/null ; echo $?) ;; esac # Check exit-code if [ "${FIND}" = "0" ]; then Display --indent 2 --text "- Consistency of group files (grpck)" --result "${STATUS_OK}" --color GREEN LogText "Result: grpck binary didn't find any errors in the group files" else Display --indent 2 --text "- Consistency of group files (grpck)" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "grpck binary found errors in one or more group files" fi unset FIND fi # ################################################################################# # # Test : AUTH-9218 # Description : Check login shells for passwordless accounts # Notes : Results should be checked Register --test-no AUTH-9218 --os "DragonFly FreeBSD NetBSD OpenBSD" --root-only YES --weight L --network NO --category security --description "Check login shells for passwordless accounts" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 LogText "Test: Checking login shells" if [ -f ${ROOTDIR}etc/master.passwd ]; then # Check for all shells, except: (/usr)/sbin/nologin /nonexistent FIND=$(${GREPBINARY} "[a-z]:\*:" ${ROOTDIR}etc/master.passwd | ${GREPBINARY} -E -v '^#|/sbin/nologin|/usr/sbin/nologin|/nonexistent' | ${SEDBINARY} 's/ /!space!/g') if [ -z "${FIND}" ]; then Display --indent 2 --text "- Login shells" --result "${STATUS_OK}" --color GREEN else Display --indent 2 --text "- Login shells" --result "${STATUS_WARNING}" --color RED for LINE in ${FIND}; do LINE=$(echo ${LINE} | ${SEDBINARY} 's/!space!/ /g') SHELL=$(echo ${LINE} | ${AWKBINARY} -F: '{ print $10 }') LogText "Output: ${LINE}" if [ -z "${SHELL}" ]; then LogText "Result: found no shell on line" else LogText "Result: found possible harmful shell ${SHELL}" if [ -f ${SHELL} ]; then LogText "Result: shell ${SHELL} does exist" FOUND=1 else LogText "Result: shell ${SHELL} does not exist" ReportSuggestion "${TEST_NO}" "Determine if account is needed, as shell ${SHELL} does not exist" fi fi done if [ ${FOUND} -eq 1 ]; then ReportWarning "${TEST_NO}" "Possible harmful shell found (for passwordless account!)" fi fi else Display --indent 2 --text "- Login shells" --result "${STATUS_SKIPPED}" --color WHITE LogText "Result: No ${ROOTDIR}etc/master.passwd file found" fi unset LINE SHELL fi # ################################################################################# # # Test : AUTH-9222 # Description : Check unique group IDs Register --test-no AUTH-9222 --weight L --network NO --category security --description "Check unique groups (IDs)" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking for non unique group ID's in /etc/group" FIND=$(${GREPBINARY} -v '^#' ${ROOTDIR}etc/group | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $3 }' | ${SORTBINARY} | uniq -d) if [ -z "${FIND}" ]; then Display --indent 2 --text "- Unique group IDs" --result "${STATUS_OK}" --color GREEN LogText "Result: All group ID's are unique" Report "auth_group_ids_unique=1" else Display --indent 2 --text "- Unique group IDs" --result "${STATUS_WARNING}" --color RED LogText "Result: Found the same group ID multiple times" for I in ${FIND}; do Report "auth_groups_nonunique[]=${I}" LogText "Non-unique group: ${I}" done ReportSuggestion "${TEST_NO}" "Check your /etc/group file and correct any inconsistencies" fi fi # ################################################################################# # # Test : AUTH-9226 # Description : Check unique group names if [ -f ${ROOTDIR}etc/group ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9226 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check unique group names" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking for non unique group names in ${ROOTDIR}etc/group" FIND=$(${GREPBINARY} -v '^#' ${ROOTDIR}etc/group | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $1 }' | ${SORTBINARY} | uniq -d) if [ -z "${FIND}" ]; then Display --indent 2 --text "- Unique group names" --result "${STATUS_OK}" --color GREEN LogText "Result: All group names are unique" Report "auth_group_names_unique=1" else Display --indent 2 --text "- Unique group names" --result "${STATUS_WARNING}" --color RED LogText "Result: Found the same group name multiple times" for I in ${FIND}; do Report "auth_groups_nonunique[]=${I}" LogText "Non-unique group: ${I}" done ReportSuggestion "${TEST_NO}" "Check your ${ROOTDIR}etc/group file and correct any inconsistencies" fi fi # ################################################################################# # # Test : AUTH-9228 # Description : Check password file consistency with pwck # Notes : Operating systems include Linux, Solaris if [ -x ${ROOTDIR}usr/sbin/pwck ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9228 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check password file consistency with pwck" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking password file consistency (pwck)" TESTED=0 case ${OS} in "Linux") FIND=$(${ROOTDIR}usr/sbin/pwck -q -r 2> /dev/null; echo $?) TESTED=1 ;; "Solaris" | "HP-UX") FIND=$(${ROOTDIR}usr/sbin/pwck 2> /dev/null; echo $?) TESTED=1 ;; *) LogText "Dev: found ${ROOTDIR}usr/sbin/pwck, but unsure how to call it on this operating system" ReportException "${TEST_NO}:1" "Found ${ROOTDIR}usr/sbin/pwck, but unsure how to call it on this operating system" ;; esac # Only display if this test has been executed if [ ${TESTED} -eq 1 -a "${FIND}" = "0" ]; then Display --indent 2 --text "- Password file consistency" --result "${STATUS_OK}" --color GREEN LogText "Result: pwck check didn't find any problems" AddHP 2 2 else Display --indent 2 --text "- Password file consistency" --result "${STATUS_SUGGESTION}" --color YELLOW LogText "Result: pwck found one or more errors/warnings in the password file." ReportSuggestion "${TEST_NO}" "Run pwck manually and correct any errors in the password file" AddHP 0 2 fi fi # ################################################################################# # # Test : AUTH-9229 # Description : Check password hashing methods vs. recommendations in crypt(5) # Notes : Applicable to all Unix-like OS # Requires read access to /etc/shadow (if it exists) ParsePasswordEntry() { METHOD=$1 case ${METHOD} in 1:\* | 1:x | 0: | *:!* | *LOCK*) # disabled | shadowed | no password | locked account (can be literal *LOCK* or something like LOCKED) ;; *:\$5\$*| *:\$6\$*) # sha256crypt | sha512crypt: check number of rounds, should be >=5000 ROUNDS=$(echo "${METHOD}" | sed -n 's/.*rounds=\([0-9]*\)\$.*/\1/gp') if [ -z "${ROUNDS}" ]; then echo 'sha256crypt/sha512crypt(default=5000rounds)' elif [ "${ROUNDS}" -lt 5000 ]; then echo 'sha256crypt/sha512crypt(<5000rounds)' fi ;; *:\$y\$* | *:\$gy\$* | *:\$2b\$* | *:\$7\$*) # yescrypt | gost-yescrypt | bcrypt | scrypt ;; *:_*) echo bsdicrypt ;; *:\$1\$*) echo md5crypt ;; *:\$3\$*) echo NT ;; *:\$md5*) echo SunMD5 ;; *:\$sha1*) echo sha1crypt ;; 13:* | 178:*) echo bigcrypt/descrypt ;; *) echo "Unknown password hashing method ${METHOD}. Please report to lynis-dev@cisofy.com" ;; esac } Register --test-no AUTH-9229 --root-only YES --weight L --network NO --category security --description "Check password hashing methods" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking password hashing methods" SHADOW=""; if [ -e ${ROOTDIR}etc/shadow ]; then SHADOW="${ROOTDIR}etc/shadow"; fi FIND=$(${CAT_BINARY} ${ROOTDIR}etc/passwd ${SHADOW} | ${AWKBINARY} -F : '{print length($2) ":" $2 }' | while read METHOD; do ParsePasswordEntry ${METHOD} done | ${SORTBINARY} -u | ${TRBINARY} '\n' ' ') if [ -z "${FIND}" ]; then Display --indent 2 --text "- Password hashing methods" --result "${STATUS_OK}" --color GREEN LogText "Result: no poor password hashing methods found" AddHP 2 2 else Display --indent 2 --text "- Password hashing methods" --result "${STATUS_SUGGESTION}" --color YELLOW LogText "Result: poor password hashing methods found: ${FIND}" ReportSuggestion "${TEST_NO}" "Check PAM configuration, add rounds if applicable and expire passwords to encrypt with new values" AddHP 0 2 fi fi # ################################################################################# # # Test : AUTH-9230 # Description : Check password hashing rounds in login.defs # Notes : Applicable to all Unix-like OS PREQS_MET="NO" if [ -f ${ROOTDIR}etc/login.defs ]; then PREQS_MET="YES" fi Register --test-no AUTH-9230 --preqs-met ${PREQS_MET} --root-only NO --weight L --network NO --category security --description "Check password hashing rounds" if [ ${SKIPTEST} -eq 0 ]; then SHA_CRYPT_MIN_ROUNDS_FIND=$(${GREPBINARY} "^SHA_CRYPT_MIN_ROUNDS" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="SHA_CRYPT_MIN_ROUNDS") { print $2 } }') SHA_CRYPT_MAX_ROUNDS_FIND=$(${GREPBINARY} "^SHA_CRYPT_MAX_ROUNDS" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="SHA_CRYPT_MAX_ROUNDS") { print $2 } }') SHA_CRYPT_ROUNDS=0 if [ -n "${SHA_CRYPT_MIN_ROUNDS_FIND}" -a -n "${SHA_CRYPT_MAX_ROUNDS_FIND}" ]; then if [ ${SHA_CRYPT_MIN_ROUNDS_FIND} -lt ${SHA_CRYPT_MAX_ROUNDS_FIND} ]; then SHA_CRYPT_ROUNDS=${SHA_CRYPT_MIN_ROUNDS_FIND} else SHA_CRYPT_ROUNDS=${SHA_CRYPT_MAX_ROUNDS_FIND} fi elif [ -z "${SHA_CRYPT_MIN_ROUNDS_FIND}" -a -n "${SHA_CRYPT_MAX_ROUNDS_FIND}" ]; then SHA_CRYPT_ROUNDS=${SHA_CRYPT_MAX_ROUNDS_FIND} elif [ -n "${SHA_CRYPT_MIN_ROUNDS_FIND}" -a -z "${SHA_CRYPT_MAX_ROUNDS_FIND}" ]; then SHA_CRYPT_ROUNDS=${SHA_CRYPT_MIN_ROUNDS_FIND} else SHA_CRYPT_ROUNDS=0 fi LogText "Test: Checking SHA_CRYPT_{MIN,MAX}_ROUNDS option in ${ROOTDIR}etc/login.defs" if [ ${SHA_CRYPT_ROUNDS} -eq 0 ]; then LogText "Result: number of password hashing rounds is not configured" Display --indent 2 --text "- Checking password hashing rounds" --result "${STATUS_DISABLED}" --color YELLOW ReportSuggestion "${TEST_NO}" "Configure password hashing rounds in /etc/login.defs" AddHP 0 2 fi if [ -n "${SHA_CRYPT_ROUNDS}" ] && [ ${SHA_CRYPT_ROUNDS} -gt 0 ]; then if [ ${SHA_CRYPT_ROUNDS} -lt 5000 ]; then LogText "Result: low number of password hashing rounds found: ${SHA_CRYPT_ROUNDS}" Display --indent 2 --text "- Password hashing rounds (minimum)" --result "${STATUS_SUGGESTION}" --color YELLOW AddHP 1 2 else LogText "Result: number of password hashing rounds is ${SHA_CRYPT_ROUNDS}" Display --indent 2 --text "- Password hashing rounds (minimum)" --result CONFIGURED --color GREEN AddHP 2 2 fi fi fi # ################################################################################# # # Test : AUTH-9234 # Description : Query user accounts # Notes : AIX: 100+ # HPUX: 100+ # macOS doesn't have any user info in /etc/passwd, users are managed with opendirectoryd) # OpenBSD/NetBSD: 1000-60000, excluding 32767 (default) # Arch Linux / CentOS / Ubuntu: 1000+ Register --test-no AUTH-9234 --weight L --network NO --category security --description "Query user accounts" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Read system users (including root user) from password database (e.g. /etc/passwd)" FIND="" case ${OS} in "AIX") LogText "AIX real users output (ID = 0, or 100+):" FIND=$(${AWKBINARY} -F: '($3 >= 100 && $3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd) ;; "FreeBSD") LogText "FreeBSD real users output (ID = 0, or 1000+, but not 65534):" FIND=$(${AWKBINARY} -F: '($3 >= 1000 && $3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd) ;; "Linux") UID_MIN="" if [ -f ${ROOTDIR}etc/login.defs ]; then UID_MIN=$(${GREPBINARY} "^UID_MIN" /etc/login.defs | ${AWKBINARY} '{print $2}') LogText "Result: found minimal user id specified: ${UID_MIN}" fi if [ "${UID_MIN}" = "" ]; then UID_MIN="1000"; fi LogText "Linux real users output (ID = 0, or ${UID_MIN}+, but not 65534):" FIND=$(${AWKBINARY} -v UID_MIN="${UID_MIN}" -F: '($3 >= UID_MIN && $3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd) ;; "macOS") LogText "macOS real users output (ID = 0, or 500-599) using dscacheutil" FIND_USERS=$(dscacheutil -q user | ${GREPBINARY} -A 3 -B 2 -e "^uid: 5[0-9][0-9]" | ${GREPBINARY} "^name: " | ${AWKBINARY} '{print $2}') if [ -n "${FIND_USERS}" ]; then for FUSERNAME in ${FIND_USERS}; do FDETAILS=$(dscacheutil -q user -a name ${FUSERNAME} | ${GREPBINARY} "^uid: " | ${AWKBINARY} '{print $2}') FIND="${FUSERNAME},${FDETAILS} ${FIND}" done else FIND="" fi ;; "NetBSD"|"OpenBSD") if [ -f ${ROOTDIR}etc/usermgmt.conf ]; then UID_RANGE=$(${GREPBINARY} "^range" ${ROOTDIR}etc/usermgmt.conf | ${AWKBINARY} '{ sub(/\.\./, "-", $2); print $2 }') fi if [ -n "${UID_RANGE}" ]; then LogText "Result: found configured user id range specified: ${UID_RANGE}" UID_MIN=$(echo $UID_RANGE | ${AWKBINARY} -F- '{ print $1 }') UID_MAX=$(echo $UID_RANGE | ${AWKBINARY} -F- '{ print $2 }') else UID_MIN=1000 UID_MAX=60000 LogText "Result: no configured user id range specified; using default ${UID_MIN}-${UID_MAX}" fi LogText "${OS} real users output (ID = 0, or ${UID_MIN}-${UID_MAX}, but not 32767):" FIND=$(${AWKBINARY} -v UID_MIN="${UID_MIN}" -v UID_MAX="${UID_MAX}" -F: '($3 >= UID_MIN && $3 <= UID_MAX && $3 != 32767) || ($3 == 0) { print $1","$3 }' /etc/passwd) ;; "Solaris") LogText "Solaris real users output (ID =0, or 100+, but not 60001/65534):" FIND=$(${AWKBINARY} -F: '($3 >= 100 && $3 != 60001 && $3 != 65534) || ($3 == 0) { print $1","$3 }' /etc/passwd) ;; *) # Want to help improving Lynis? Determine what user IDs belong to normal user accounts ReportException "${TEST_NO}:1" "Can not determine user accounts" ;; esac # Check if we got any output if [ -z "${FIND}" ]; then Display --indent 4 --text "Result: No users found/unknown result" LogText "Result: Querying of system users skipped" Display --indent 2 --text "- Query system users (non daemons)" --result "${STATUS_UNKNOWN}" --color YELLOW else Display --indent 2 --text "- Query system users (non daemons)" --result "${STATUS_DONE}" --color GREEN for I in ${FIND}; do if [ -n "${I}" ]; then LogText "Real user: ${I}" Report "real_user[]=${I}" fi done fi fi # ################################################################################# # # Test : AUTH-9240 # Description : Query NIS+ authentication support Register --test-no AUTH-9240 --weight L --network NO --category security --description "Query NIS+ authentication support" if [ ${SKIPTEST} -eq 0 ]; then if [ -f /etc/nsswitch.conf ]; then FIND=$(${GREPBINARY} -E "^passwd" /etc/nsswitch.conf | ${GREPBINARY} -E "compat|nisplus") if [ -z "${FIND}" ]; then LogText "Result: NIS+ authentication not enabled" Display --indent 2 --text "- NIS+ authentication support" --result "${STATUS_NOT_ENABLED}" --color WHITE else FIND2=$(${GREPBINARY} -E "^passwd_compat" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} "nisplus") FIND3=$(${GREPBINARY} -E "^passwd" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} "nisplus") if [ -n "${FIND2}" -o -n "${FIND3}" ]; then LogText "Result: NIS+ authentication enabled" Display --indent 2 --text "- NIS+ authentication support" --result "${STATUS_ENABLED}" --color GREEN else LogText "Result: NIS+ authentication not enabled" Display --indent 2 --text "- NIS+ authentication support" --result "${STATUS_NOT_ENABLED}" --color WHITE fi fi else LogText "Result: /etc/nsswitch.conf not found" fi fi # ################################################################################# # # Test : AUTH-9242 # Description : Query NIS authentication support Register --test-no AUTH-9242 --weight L --network NO --category security --description "Query NIS authentication support" if [ ${SKIPTEST} -eq 0 ]; then if [ -f /etc/nsswitch.conf ]; then FIND=$(${GREPBINARY} -E "^passwd" /etc/nsswitch.conf | ${GREPBINARY} -E "compat|nis" | ${GREPBINARY} -v "nisplus") if [ -z "${FIND}" ]; then LogText "Result: NIS authentication not enabled" Display --indent 2 --text "- NIS authentication support" --result "${STATUS_NOT_ENABLED}" --color WHITE else FIND2=$(${GREPBINARY} -E "^passwd_compat" /etc/nsswitch.conf | ${GREPBINARY} "nis" | ${GREPBINARY} -v "nisplus") FIND3=$(${GREPBINARY} -E "^passwd" /etc/nsswitch.conf | ${GREPBINARY} "nis" | ${GREPBINARY} -v "nisplus") if [ -n "${FIND2}" -o -n "${FIND3}" ]; then LogText "Result: NIS authentication enabled" Display --indent 2 --text "- NIS authentication support" --result "${STATUS_ENABLED}" --color GREEN else LogText "Result: NIS authentication not enabled" Display --indent 2 --text "- NIS authentication support" --result "${STATUS_NOT_ENABLED}" --color WHITE fi fi else LogText "Result: /etc/nsswitch.conf not found" fi fi # ################################################################################# # # Test : AUTH-9250 # Description : Check for sudoers file Register --test-no AUTH-9250 --weight L --network NO --category security --description "Checking sudoers file" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 for I in ${SUDOERS_LOCATIONS}; do LogText "Test: checking presence ${I}" if [ -f ${I} ]; then FOUND=1 SUDOERS_FILE="${I}" LogText "Result: found file (${SUDOERS_FILE})" else LogText "Result: file ${I} not found" fi done if [ ${FOUND} -eq 1 ]; then LogText "Result: sudoers file found (${SUDOERS_FILE})" Display --indent 2 --text "- Sudoers file(s)" --result "${STATUS_FOUND}" --color GREEN else LogText "Result: sudoers file NOT found" Display --indent 2 --text "- Sudoers file" --result "${STATUS_NOT_FOUND}" --color YELLOW fi fi # ################################################################################# # # Test : AUTH-9252 # Description : Check ownership and permissions for sudo configuration files if [ -n "${SUDOERS_FILE}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9252 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description "Check ownership and permissions for sudo configuration files" if [ ${SKIPTEST} -eq 0 ]; then SUDO_CONFIG_FILES="${SUDOERS_FILE}" SUDOERS_D="${SUDOERS_FILE}.d" if [ -d "${SUDOERS_D}" ]; then LogText "Test: checking drop-in directory (${SUDOERS_D})" FIND=$(${LSBINARY} -ld ${SUDOERS_D} | ${CUTBINARY} -c 2-10) FIND2=$(${LSBINARY} -lnd ${SUDOERS_D} | ${AWKBINARY} '{print $3$4}') LogText "Result: Found directory permissions: ${FIND} and owner UID GID: ${FIND2}" case "${FIND}" in rwx[r-][w-][x-]--- ) LogText "Result: directory ${SUDOERS_D} permissions OK" if [ "${FIND2}" = "00" ]; then LogText "Result: directory ${SUDOERS_D} ownership OK" Display --indent 4 --text "- Permissions for directory: ${SUDOERS_D}" --result "${STATUS_OK}" --color GREEN else LogText "Result: directory ${SUDOERS_D} has possibly unsafe ownership" Display --indent 4 --text "- Permissions for directory: ${SUDOERS_D}" --result "${STATUS_WARNING}" --color RED fi ;; * ) LogText "Result: directory ${SUDOERS_D} has possibly unsafe permissions" if [ "${FIND2}" = "00" ]; then LogText "Result: directory ${SUDOERS_D} ownership OK" else LogText "Result: directory ${SUDOERS_D} has possibly unsafe ownership" fi Display --indent 4 --text "- Permissions for directory: ${SUDOERS_D}" --result "${STATUS_WARNING}" --color RED ;; esac SUDO_CONFIG_FILES="${SUDO_CONFIG_FILES} $(${FINDBINARY} -L ${SUDOERS_D} -type f -print)" fi for f in ${SUDO_CONFIG_FILES}; do LogText "Test: checking file (${f})" FIND=$(${LSBINARY} -l ${f} | ${CUTBINARY} -c 2-10) FIND2=$(${LSBINARY} -ln ${f} | ${AWKBINARY} '{print $3$4}') LogText "Result: Found file permissions: ${FIND} and owner UID GID: ${FIND2}" case "${FIND}" in r[w-]-[r-][w-]---- ) LogText "Result: file ${f} permissions OK" if [ "${FIND2}" = "00" ]; then LogText "Result: file ${f} ownership OK" Display --indent 4 --text "- Permissions for: ${f}" --result "${STATUS_OK}" --color GREEN else LogText "Result: file ${f} has possibly unsafe ownership" Display --indent 4 --text "- Permissions for: ${f}" --result "${STATUS_WARNING}" --color RED fi ;; * ) LogText "Result: file ${f} has possibly unsafe permissions" if [ "${FIND2}" = "00" ]; then LogText "Result: file ${f} ownership OK" else LogText "Result: file ${f} has possibly unsafe ownership" fi Display --indent 4 --text "- Permissions for: ${f}" --result "${STATUS_WARNING}" --color RED ;; esac done fi # ################################################################################# # # Test : AUTH-9254 # Description : Solaris test to check passwordless accounts Register --test-no AUTH-9254 --os Solaris --weight L --network NO --root-only YES --category security --description "Solaris passwordless accounts" if [ ${SKIPTEST} -eq 0 ]; then FIND=$(logins -p | ${AWKBINARY} '{ print $1 }') if [ -z "${FIND}" ]; then LogText "Result: no passwordless accounts found" Display --indent 2 --text "- Passwordless accounts on Solaris" --result "${STATUS_OK}" --color GREEN else for I in ${FIND}; do ReportWarning "${TEST_NO}" "Found passwordless account (${I})" done Display --indent 2 --text "- Passwordless accounts on Solaris" --result "${STATUS_WARNING}" --color RED fi fi # ################################################################################# # # Test : AUTH-9262 # Description : Search for PAM password strength testing libraries Register --test-no AUTH-9262 --weight L --network NO --category security --description "Checking presence password strength testing tools (PAM)" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 FOUND_CRACKLIB=0 FOUND_PASSWDQC=0 FOUND_PWQUALITY=0 # Cracklib LogText "Searching PAM password testing modules (cracklib, passwdqc, pwquality)" for I in ${PAM_FILE_LOCATIONS}; do if [ -f ${I}/pam_cracklib.so ]; then FOUND_CRACKLIB=1 FOUND=1 LogText "Result: found pam_cracklib.so (crack library PAM) in ${I}" fi if [ -f ${I}/pam_passwdqc.so ]; then FOUND_PASSWDQC=1 FOUND=1 LogText "Result: found pam_passwdqc.so (passwd quality control PAM) in ${I}" fi if [ -f ${I}/pam_pwquality.so ]; then FOUND_PWQUALITY=1 FOUND=1 LogText "Result: found pam_pwquality.so (password quality control PAM) in ${I}" fi done # Cracklib if [ ${FOUND_CRACKLIB} -eq 1 ]; then LogText "Result: pam_cracklib.so found" Report "pam_cracklib=1" else LogText "Result: pam_cracklib.so NOT found (crack library PAM)" fi # Password quality control if [ ${FOUND_PASSWDQC} -eq 1 ]; then LogText "Result: pam_passwdqc.so found" Report "pam_passwdqc=1" else LogText "Result: pam_passwdqc.so NOT found (passwd quality control PAM)" fi # pwquality module if [ ${FOUND_PWQUALITY} -eq 1 ]; then LogText "Result: pam_pwquality.so found" Report "pam_pwquality=1" else LogText "Result: pam_pwquality.so NOT found (pwquality control PAM)" fi if [ ${FOUND} -eq 0 ]; then Display --indent 2 --text "- PAM password strength tools" --result "${STATUS_SUGGESTION}" --color YELLOW LogText "Result: no PAM modules for password strength testing found" ReportSuggestion "${TEST_NO}" "Install a PAM module for password strength testing like pam_cracklib or pam_passwdqc or libpam-passwdqc" AddHP 0 3 else Display --indent 2 --text "- PAM password strength tools" --result "${STATUS_OK}" --color GREEN LogText "Result: found at least one PAM module for password strength testing" AddHP 3 3 fi fi # ################################################################################# # # Test : AUTH-9264 # Description : Scan /etc/pam.conf file Register --test-no AUTH-9264 --weight L --network NO --category security --description "Checking presence pam.conf" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking file /etc/pam.conf" if [ -f ${ROOTDIR}etc/pam.conf ]; then LogText "Result: file ${ROOTDIR}etc/pam.conf exists" Display --indent 2 --text "- PAM configuration files (pam.conf)" --result "${STATUS_FOUND}" --color GREEN LogText "Test: searching PAM configuration files" FIND=$(${GREPBINARY} -E -v "^#" ${ROOTDIR}etc/pam.conf | ${GREPBINARY} -E -v "^$" | ${SEDBINARY} 's/[[:space:]]/ /g' | ${SEDBINARY} 's/ / /g' | ${SEDBINARY} 's/ /:space:/g') if [ -z "${FIND}" ]; then LogText "Result: File has no configuration options defined (empty, or only filled with comments and empty lines)" else LogText "Result: found one or more configuration lines" for LINE in ${FIND}; do LINE=$(echo ${LINE} | ${SEDBINARY} 's/:space:/ /g') LogText "Found line: ${LINE}" done fi else LogText "Result: file /etc/pam.conf could not be found" Display --indent 2 --text "- PAM configuration file (pam.conf)" --result "${STATUS_NOT_FOUND}" --color WHITE fi fi # ################################################################################# # # Test : AUTH-9266 # Description : Searching available PAM configurations (/etc/pam.d) Register --test-no AUTH-9266 --weight L --network NO --category security --description "Checking presence pam.d files" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking directory ${ROOTDIR}etc/pam.d" if [ -d ${ROOTDIR}etc/pam.d ]; then LogText "Result: directory /etc/pam.d exists" Display --indent 2 --text "- PAM configuration files (pam.d)" --result "${STATUS_FOUND}" --color GREEN LogText "Test: searching PAM configuration files" FIND=$(${FINDBINARY} -L ${ROOTDIR}etc/pam.d \! -name "*.pam-old" -type f -print | sort) for FILE in ${FIND}; do LogText "Found file: ${FILE}" done else LogText "Result: directory /etc/pam.d could not be found" Display --indent 2 --text "- PAM configuration files (pam.d)" --result "${STATUS_NOT_FOUND}" --color WHITE fi fi # ################################################################################# # # Test : AUTH-9268 # Description : Searching available PAM files # Notes : PAM is used on AIX, FreeBSD, Linux, HPUX, NetBSD, Solaris OS_USES_PAM="AIX DragonFly FreeBSD Linux HPUX NetBSD Solaris" Register --test-no AUTH-9268 --os "${OS_USES_PAM}" --weight L --network NO --category security --description "Checking presence pam.d files" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 LogText "Test: Searching pam modules" for DIR in ${PAM_FILE_LOCATIONS}; do LogText "Test: Checking ${DIR}" if [ -d ${DIR} -a ! -L ${DIR} ]; then LogText "Result: directory ${DIR} exists" # Search in the specified directory if [ "${OS}" = "AIX" -o "${OS}" = "Solaris" ]; then # AIX/Solaris does not support -maxdepth FIND=$(find ${DIR} -type f -name "pam_*.so" -print | sort) else FIND=$(find ${DIR} -maxdepth 1 -type f -name "pam_*.so" -print | sort) fi if [ -n "${FIND}" ]; then FOUND=1; fi for FILE in ${FIND}; do LogText "Found file: ${FILE}" Report "pam_module[]=${FILE}" done else LogText "Result: directory ${DIR} could not be found or is a symlink to another directory" fi done # Check if we found at least one module if [ ${FOUND} -eq 0 ]; then Display --indent 2 --text "- PAM modules" --result "${STATUS_NOT_FOUND}" --color WHITE LogText "Result: no PAM modules found" else Display --indent 2 --text "- PAM modules" --result "${STATUS_FOUND}" --color GREEN fi unset DIR FILE FIND fi # ################################################################################# # # Test : AUTH-9278 # Description : Search LDAP support in PAM files Register --test-no AUTH-9278 --weight L --network NO --category security --description "Determine LDAP support in PAM files" if [ ${SKIPTEST} -eq 0 ]; then AUTH_FILES="${ROOTDIR}etc/pam.d/common-auth ${ROOTDIR}etc/pam.d/system-auth" for FILE in ${AUTH_FILES}; do LogText "Test: checking presence ${FILE}" if [ -f ${FILE} ]; then LogText "Result: file ${FILE} exists" LogText "Test: checking presence LDAP module" FIND=$(${GREPBINARY} "^auth.*ldap" ${FILE}) if [ -n "${FIND}" ]; then LogText "Result: LDAP module present" LogText "Output: ${FIND}" LDAP_AUTH_ENABLED=1 LDAP_PAM_ENABLED=1 else LogText "Result: LDAP module not found" fi else LogText "Result: file ${FILE} not found, skipping test" fi done if [ ${LDAP_PAM_ENABLED} -eq 1 ]; then Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_FOUND}" --color GREEN else Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_NOT_FOUND}" --color WHITE fi fi # ################################################################################# # # Test : AUTH-9282, AUTH-9283, and AUTH-9284 # Note : Every Linux based operating system seem to have different passwd # options, so we have to check the version first. if [ "${OS}" = "Linux" ]; then if [ "${OS_REDHAT_OR_CLONE}" -eq 0 ]; then case ${LINUX_VERSION} in "SuSE") PREQS_MET="YES" FIND_P=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2=="P" && $5=="99999") print $1 }') FIND2=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2=="NP") print $1 }') FIND3=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2=="L") print $1 }' | sort | uniq) ;; *) PREQS_MET="YES" FIND_P=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2=="P" && $5=="99999") print $1 }') FIND2=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2=="NP") print $1 }') FIND3=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2=="L") print $1 }' | sort | uniq) ;; esac elif [ "${OS_REDHAT_OR_CLONE}" -eq 1 ]; then PREQS_MET="YES" FIND_P=$(for I in $(${AWKBINARY} -F: '{print $1}' "${ROOTDIR}etc/passwd") ; do passwd -S "$I" | ${AWKBINARY} '{ if ($2=="PS" && $5=="99999") print $1 }' ; done) FIND2=$(for I in $(${AWKBINARY} -F: '{print $1}' "${ROOTDIR}etc/passwd") ; do passwd -S "$I" | ${AWKBINARY} '{ if ($2=="NP") print $1 }' ; done) FIND3=$(for I in $(${AWKBINARY} -F: '{print $1}' "${ROOTDIR}etc/passwd") ; do passwd -S "$I" | ${AWKBINARY} '{ if ($2=="L" || $2=="LK") print $1 }' | sort | uniq ; done) else LogText "Result: skipping test for this Linux version" ReportManual "AUTH-9282:01" PREQS_MET="NO" FIND_P="" FIND2="" FIND3="" fi else PREQS_MET="NO" fi # Test : AUTH-9282 # Description : Search password protected accounts without expire (Linux) Register --test-no AUTH-9282 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking password protected account without expire date" if [ "${SKIPTEST}" -eq 0 ]; then LogText "Test: Checking Linux version and password expire date status" if [ -z "${FIND_P}" ]; then LogText "Result: all accounts seem to have an expire date" Display --indent 2 --text "- Accounts without expire date" --result "${STATUS_OK}" --color GREEN else LogText "Result: found one or more accounts without expire date set" for I in ${FIND_P}; do LogText "Account without expire date: ${I}" done Display --indent 2 --text "- Accounts without expire date" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "When possible set expire dates for all password protected accounts" fi fi # Test : AUTH-9283 # Description : Search passwordless accounts # Notes : requires FIND2 variable Register --test-no AUTH-9283 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking accounts without password" if [ "${SKIPTEST}" -eq 0 ]; then LogText "Test: Checking passwordless accounts" if [ -z "${FIND2}" ]; then LogText "Result: all accounts seem to have a password" Display --indent 2 --text "- Accounts without password" --result "${STATUS_OK}" --color GREEN else LogText "Result: found one or more accounts without password" for I in ${FIND2}; do LogText "Account without password: ${I}" Report "account_without_password[]=${I}" done Display --indent 2 --text "- Accounts without password" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "Found accounts without password" fi fi # Test : AUTH-9284 # Description : Check locked user accounts in /etc/passwd # Notes : requires FIND3 variable Register --test-no AUTH-9284 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check locked user accounts in /etc/passwd" if [ "${SKIPTEST}" -eq 0 ]; then LogText "Test: Checking locked accounts" NON_SYSTEM_ACCOUNTS=$(${AWKBINARY} -F : '$3 > 999 && $3 != 65534 {print $1}' ${ROOTDIR}etc/passwd | ${SORTBINARY} | ${UNIQBINARY}) LOCKED_NON_SYSTEM_ACCOUNTS=0 for account in ${FIND3}; do if echo "${NON_SYSTEM_ACCOUNTS}" | ${GREPBINARY} -w "${account}" > /dev/null ; then LOCKED_NON_SYSTEM_ACCOUNTS=$((LOCKED_NON_SYSTEM_ACCOUNTS + 1)) fi done if [ ${LOCKED_NON_SYSTEM_ACCOUNTS} -eq 0 ]; then LogText "Result: all accounts seem to be unlocked" Display --indent 2 --text "- Locked accounts" --result "${STATUS_OK}" --color GREEN else LogText "Result: found one or more locked accounts" for account in ${FIND3}; do if echo "${NON_SYSTEM_ACCOUNTS}" | ${GREPBINARY} -w "${account}" > /dev/null ; then LogText "Locked account: ${account}" Report "locked_account[]=${account}" fi done Display --indent 2 --text "- Locked accounts" --result "${STATUS_FOUND}" --color RED ReportSuggestion "${TEST_NO}" "Look at the locked accounts and consider removing them" fi unset account LOCKED_NON_SYSTEM_ACCOUNTS NON_SYSTEM_ACCOUNTS fi unset FIND1 FIND2 FIND3 # ################################################################################# # # Test : AUTH-9286 # Description : Check user password aging # Notes : MIN = minimum age, avoid rotation of passwords too quickly # : MAX = maximum age, ensure regular change of passwords PREQS_MET="NO" if [ -f ${ROOTDIR}etc/login.defs ]; then PREQS_MET="YES" # Future TODO: check if PAM overrule these settings fi Register --test-no AUTH-9286 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking user password aging" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking PASS_MIN_DAYS option in ${ROOTDIR}etc/login.defs" FIND=$(${GREPBINARY} "^PASS_MIN_DAYS" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="PASS_MIN_DAYS") { print $2 } }') if [ -z "${FIND}" -o "${FIND}" = "0" ]; then LogText "Result: password minimum age is not configured" Display --indent 2 --text "- Checking user password aging (minimum)" --result "${STATUS_DISABLED}" --color YELLOW ReportSuggestion "${TEST_NO}" "Configure minimum password age in /etc/login.defs" AddHP 0 1 else LogText "Result: password needs to be at least ${FIND} days old" PASSWORD_MINIMUM_DAYS=${FIND} Display --indent 2 --text "- User password aging (minimum)" --result CONFIGURED --color GREEN AddHP 3 3 fi LogText "Test: Checking PASS_MAX_DAYS option in ${ROOTDIR}etc/login.defs " FIND=$(${GREPBINARY} "^PASS_MAX_DAYS" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="PASS_MAX_DAYS") { print $2 } }') if [ -z "${FIND}" -o "${FIND}" = "99999" ]; then LogText "Result: password aging limits are not configured" Display --indent 2 --text "- User password aging (maximum)" --result "${STATUS_DISABLED}" --color YELLOW ReportSuggestion "${TEST_NO}" "Configure maximum password age in /etc/login.defs" AddHP 0 1 else LogText "Result: max password age is ${FIND} days" PASSWORD_MAXIMUM_DAYS=${FIND} Display --indent 2 --text "- User password aging (maximum)" --result CONFIGURED --color GREEN AddHP 3 3 fi fi # ################################################################################# # # Test : AUTH-9288 # Description : Determine which accounts have an expired password # Notes : This test might not work (yet) on all platforms if [ -f ${ROOTDIR}etc/shadow ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9288 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description "Checking for expired passwords" if [ ${SKIPTEST} -eq 0 ]; then if FileIsReadable ${ROOTDIR}etc/shadow; then if [ "${OS}" = "Solaris" ]; then NOW=$(nawk 'BEGIN{print srand()}') else NOW=$(date "+%s") fi DAYS_SINCE_EPOCH=$((NOW / 86400)) LogText "Data: Days since epoch is ${DAYS_SINCE_EPOCH}" LogText "Test: collecting accounts which have an expired password (last day changed + maximum change time)" # Skip fields with a !, *, or x, or !* (field $3 is last changed, $5 is maximum changed) FIND=$(${GREPBINARY} -E -v ":[\!\*x]([\*\!])?:" /etc/shadow | ${AWKBINARY} -v today=${DAYS_SINCE_EPOCH} -F: '{ if (($5!="") && (today>$3+$5)) { print $1 }}') if [ -n "${FIND}" ]; then for ACCOUNT in ${FIND}; do LogText "Result: password of user ${ACCOUNT} has been expired" Report "account_password_expired[]=${ACCOUNT}" done AddHP 0 10 Display --indent 2 --text "- Checking expired passwords" --result "${STATUS_FOUND}" --color RED ReportSuggestion "${TEST_NO}" "Delete accounts which are no longer used" else LogText "Result: good, no passwords have been expired" Display --indent 2 --text "- Checking expired passwords" --result "${STATUS_OK}" --color GREEN AddHP 10 10 fi else Display --indent 2 --text "- Checking expired passwords" --result "${STATUS_SKIPPED}" --color YELLOW fi fi # ################################################################################# # # Test : AUTH-9304 # Description : Check if single user mode login is properly configured in Solaris # Notes : sulogin should be called from svm script (Solaris <10) in /etc/rcS.d Register --test-no AUTH-9304 --os Solaris --weight L --network NO --category security --description "Check single user login configuration" if [ ${SKIPTEST} -eq 0 ]; then # Check if file exists (Solaris 10 does not have this file by default) if [ -f ${ROOTDIR}etc/default/sulogin ]; then LogText "Result: file ${ROOTDIR}etc/default/sulogin exists" LogText "Test: checking presence PASSREQ=NO" FIND=$(${GREPBINARY} "^PASSREQ=NO" ${ROOTDIR}etc/default/sulogin) if [ -z "${FIND}" ]; then LogText "Result: option not present or configured to request a password at single user mode login" Display --indent 2 --text "- Checking Solaris /etc/default/sulogin file" --result "${STATUS_OK}" --color GREEN AddHP 1 1 else LogText "Result: option present, no password needed at single user mode login" Display --indent 2 --text "- Checking Solaris /etc/default/sulogin file" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "No password needed for single user mode login" AddHP 0 1 fi else LogText "Result: file /etc/default/sulogin does not exist" fi fi # ################################################################################# # # Test : AUTH-9306 # Description : Check if authentication is needed to boot the system # Notes : :d_boot_authenticate: is a good option for production machines to # avoid unauthorized booting of systems. Option :d_boot_authentication@: # disabled a required login. Register --test-no AUTH-9306 --os HP-UX --weight L --network NO --category security --description "Check single boot authentication" if [ ${SKIPTEST} -eq 0 ]; then # Check if file exists LogText "Test: Searching /tcb/files/auth/system/default" if [ -f ${ROOTDIR}tcb/files/auth/system/default ]; then LogText "Result: file ${ROOTDIR}tcb/files/auth/system/default exists" LogText "Test: checking presence :d_boot_authenticate@:" FIND=$(${GREPBINARY} "^:d_boot_authenticate@" /tcb/files/auth/system/default) if [ -z "${FIND}" ]; then LogText "Result: option not set, password is needed at boot" Display --indent 2 --text "- Checking HP-UX boot authentication" --result "${STATUS_OK}" --color GREEN AddHP 1 1 else LogText "Result: option present, no password needed at single user mode login" Display --indent 2 --text "- Checking HP-UX boot authentication" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Set password for system boot" AddHP 0 1 fi else LogText "Result: file ${ROOTDIR}tcb/files/auth/system/default does not exist" fi fi # ################################################################################# # # Test : AUTH-9308 # Description : Check single user mode login for Linux Register --test-no AUTH-9308 --os Linux --weight L --network NO --category security --description "Check single user login configuration" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 TEST_PERFORMED=0 if [ ${HAS_SYSTEMD} -eq 0 ]; then # Check inittab LogText "Test: Searching ${ROOTDIR}etc/inittab" if [ -f ${ROOTDIR}etc/inittab ]; then TEST_PERFORMED=1 LogText "Result: file ${ROOTDIR}etc/inittab exists" LogText "Test: checking presence sulogin for single user mode" FIND=$(${GREPBINARY} -E "^[a-zA-Z0-9~]+:S:(respawn|wait):/sbin/sulogin" /etc/inittab) FIND2=$(${GREPBINARY} -E "^su:S:(respawn|wait):/sbin/sulogin" /etc/inittab) if [ -n "${FIND}" -o -n "${FIND2}" ]; then FOUND=1 LogText "Result: found sulogin, so single user is protected" fi else LogText "Result: file ${ROOTDIR}etc/inittab does not exist" fi # Check init LogText "Test: Searching ${ROOTDIR}etc/sysconfig/init" if [ -f ${ROOTDIR}etc/sysconfig/init ]; then TEST_PERFORMED=1 LogText "Result: file ${ROOTDIR}etc/sysconfig/init exists" LogText "Test: checking presence sulogin for single user mode" FIND=$(${GREPBINARY} "^SINGLE=/sbin/sulogin" ${ROOTDIR}etc/sysconfig/init) if [ -n "${FIND}" ]; then FOUND=1 LogText "Result: found sulogin, so single user is protected" fi else LogText "Result: file ${ROOTDIR}etc/sysconfig/init does not exist" fi fi # Systemd support SYSTEMD_DIRECTORY="/lib/systemd/system" if [ -d ${SYSTEMD_DIRECTORY} ]; then FILES="console-shell.service emergency.service rescue.service" LogText "Test: going to check several systemd targets now" for I in ${FILES}; do FILE="${SYSTEMD_DIRECTORY}/${I}" LogText "Test: checking if target ${I} is available (${FILE})" if [ -f ${FILE} ]; then # Mark test as performed only when at least 1 target exists (e.g. Ubuntu 14.04 has limited systemd support) TEST_PERFORMED=1 LogText "Result: found target ${I}" FIND=$(${GREPBINARY} -E "^ExecStart=" ${FILE} | ${GREPBINARY} "sulogin") if [ "${FIND}" = "" ]; then LogText "Result: did not find sulogin specified, possible risk of getting into single user mode without authentication" else LogText "Result: sulogin was found, which is a good measure to protect single user mode" FOUND=1 fi else LogText "Result: target ${I} not found" fi done fi if [ ${TEST_PERFORMED} -eq 1 ]; then if [ ${FOUND} -eq 0 ]; then LogText "Result: option not set, no password needed at single user mode boot" Display --indent 2 --text "- Checking Linux single user mode authentication" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "No password set for single mode" ReportSuggestion "${TEST_NO}" "Set password for single user mode to minimize physical access attack surface" AddHP 0 2 else LogText "Result: option set, password is needed at single user mode boot" Display --indent 2 --text "- Checking Linux single user mode authentication" --result "${STATUS_OK}" --color GREEN AddHP 2 2 fi else LogText "Result: no tests performed" fi fi # ################################################################################# # # Test : AUTH-9328 # Description : Check default umask in common files # Notes: This test should be moved later to shells section # /etc/login.defs # pam_umask Register --test-no AUTH-9328 --weight L --network NO --category security --description "Default umask values" if [ ${SKIPTEST} -eq 0 ]; then Display --indent 2 --text "- Determining default umask" GOOD_UMASK=0 WEAK_UMASK=0 # /etc/profile.d LogText "Test: Checking ${ROOTDIR}etc/profile.d directory" if [ -d ${ROOTDIR}etc/profile.d ]; then FOUND=0 FIND=$(ls ${ROOTDIR}etc/profile.d/* 2> /dev/null) if [ -n "${FIND}" ]; then LogText "Result: found /etc/profile.d, with one or more files in it" for FILE in ${FIND}; do HAS_MASK=$(${GREPBINARY} umask ${FILE} 2> /dev/null | ${SEDBINARY} 's/^[ \t]*//' | ${GREPBINARY} -v "^#" | ${AWKBINARY} '{ print $2 }') for MASK in ${HAS_MASK}; do if [ "${MASK}" = "077" -o "${MASK}" = "027" -o "${MASK}" = "0077" -o "${MASK}" = "0027" ]; then LogText "Result: found a strong umask '${MASK}' set in ${FILE}" GOOD_UMASK=1 else LogText "Result: found a weak umask '${MASK}' set in ${FILE}" WEAK_UMASK=1 fi done done else LogText "Result: found /etc/profile.d, but it does not contain any files" fi else LogText "Result: /etc/profile.d not found" fi # Test /etc/profile (only if we didn't find a good umask in profile.d) LogText "Test: Checking /etc/profile" if [ -f /etc/profile -a ${GOOD_UMASK} -eq 0 ]; then LogText "Result: file /etc/profile exists" LogText "Test: Checking umask value in /etc/profile" FIND=$(${GREPBINARY} "umask" /etc/profile | ${SEDBINARY} 's/^[ \t]*//' | ${GREPBINARY} -v "^#" | ${AWKBINARY} '{ print $2 }') FIND2=$(${GREPBINARY} "umask" /etc/profile | ${SEDBINARY} 's/^[ \t]*//' | ${GREPBINARY} -v "^#" | ${AWKBINARY} '{ print $2 }' | wc -l) FOUND_UMASK=0 if [ "${FIND2}" = "0" ]; then LogText "Result: did not find umask in /etc/profile" elif [ "${FIND2}" = "1" ]; then LogText "Result: found umask (prefixed with spaces)" FOUND_UMASK=1 if [ ! "${FIND}" = "077" -a ! "${FIND}" = "027" -a ! "${FIND}" = "0077" -a ! "${FIND}" = "0027" ]; then LogText "Result: found umask ${FIND}, which could be more strict" WEAK_UMASK=1 else LogText "Result: found umask ${FIND}, which is fine" GOOD_UMASK=1 fi # Found more than 1 umask value in profile else LogText "Result: found multiple umask values configured in /etc/profile" FOUND_UMASK=1 for I in ${FIND}; do if [ ! "${I}" = "077" -a ! "${I}" = "027" -a ! "${I}" = "0077" -a ! "${I}" = "0027" ]; then LogText "Result: umask ${I} could be more strict" WEAK_UMASK=1 AddHP 1 2 else LogText "Result: Found umask ${I}, which is fine" AddHP 2 2 fi done fi if [ ${FOUND_UMASK} -eq 1 ]; then if [ ${WEAK_UMASK} -eq 0 ]; then Display --indent 4 --text "- umask (/etc/profile and /etc/profile.d)" --result "${STATUS_OK}" --color GREEN AddHP 2 2 elif [ ${GOOD_UMASK} -eq 1 -a ${WEAK_UMASK} -eq 1 ]; then Display --indent 4 --text "- umask (/etc/profile and /etc/profile.d)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Some umasks found could be more strict (e.g. 027)" AddHP 1 2 else Display --indent 4 --text "- umask (/etc/profile and /etc/profile.d)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/profile or /etc/profile.d/custom.sh could be more strict (e.g. 027)" AddHP 0 2 fi else # Some operating systems don't have a default umask defined in /etc/profile (Debian) LogText "Result: found no umask. Please check if this is correct" Display --indent 4 --text "- umask (/etc/profile)" --result "${STATUS_NOT_FOUND}" --color YELLOW fi fi # /etc/passwd LogText "Test: Checking umask entries in /etc/passwd (pam_umask)" if [ -f /etc/passwd ]; then LogText "Result: file /etc/passwd exists" LogText "Test: Checking umask value in /etc/passwd" FIND=$(${GREPBINARY} "umask=" /etc/passwd) if [ "${FIND}" = "" ]; then ReportManual "AUTH-9328:03" fi else LogText "Result: file /etc/passwd does not exist" fi # /etc/login.defs LogText "Test: Checking /etc/login.defs" if [ -f /etc/login.defs ]; then LogText "Result: file /etc/login.defs exists" LogText "Test: Checking umask value in /etc/login.defs" FIND=$(${GREPBINARY} "^UMASK" /etc/login.defs | ${AWKBINARY} '{ print $2 }') if [ "${FIND}" = "" ]; then LogText "Result: umask value is not configured (most likely it will have the default 022 value)" Display --indent 4 --text "- umask (/etc/login.defs)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/login.defs could not be found and defaults usually to 022, which could be more strict like 027" AddHP 1 2 elif [ "${FIND}" = "077" -o "${FIND}" = "027" -o "${FIND}" = "0077" -o "${FIND}" = "0027" ]; then LogText "Result: umask is ${FIND}, which is fine" Display --indent 4 --text "- umask (/etc/login.defs)" --result "${STATUS_OK}" --color GREEN AddHP 2 2 else LogText "Result: found umask ${FIND}, which could be improved" Display --indent 4 --text "- umask (/etc/login.defs)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/login.defs could be more strict like 027" AddHP 0 2 fi else LogText "Result: file /etc/login.defs does not exist" fi # Red Hat /etc/init.d/functions LogText "Test: Checking /etc/init.d/functions" if [ -f /etc/init.d/functions ]; then LogText "Result: file /etc/init.d/functions exists" LogText "Test: Checking umask value in /etc/init.d/functions" FIND=$(${GREPBINARY} "^umask" /etc/init.d/functions | ${AWKBINARY} '{ print $2 }') if [ "${FIND}" = "" ]; then LogText "Result: umask is not configured" Display --indent 4 --text "- umask (/etc/init.d/functions)" --result "${STATUS_NONE}" --color WHITE elif [ "${FIND}" = "077" -o "${FIND}" = "027" -o "${FIND}" = "0077" -o "${FIND}" = "0027" ]; then LogText "Result: umask is ${FIND}, which is fine" Display --indent 4 --text "- umask (/etc/init.d/functions)" --result "${STATUS_OK}" --color GREEN AddHP 2 2 else LogText "Result: found umask ${FIND}, which could be improved" Display --indent 4 --text "- umask (/etc/init.d/functions)" --result "${STATUS_SUGGESTION}" --color YELLOW AddHP 0 2 fi else LogText "Result: file /etc/init.d/functions does not exist" fi # /etc/init.d/rc LogText "Test: Checking /etc/init.d/rc" if [ -f /etc/init.d/rc ]; then LogText "Result: file /etc/init.d/rc exists" LogText "Test: Checking UMASK value in /etc/init.d/rc" FIND=$(${GREPBINARY} -i "^UMASK" /etc/init.d/rc | ${AWKBINARY} '{ print $2 }') if [ "${FIND}" = "" ]; then LogText "Result: UMASK value is not configured (most likely it will have the default 022 value)" Display --indent 4 --text "- Checking umask (/etc/init.d/rc)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/init.d/rc could not be found and defaults usually to 022, which could be more strict like 027" AddHP 1 2 elif [ "${FIND}" = "077" -o "${FIND}" = "027" -o "${FIND}" = "0077" -o "${FIND}" = "0027" ]; then LogText "Result: umask is ${FIND}, which is fine" Display --indent 4 --text "- umask (/etc/init.d/rc)" --result "${STATUS_OK}" --color GREEN AddHP 2 2 else LogText "Result: found umask ${FIND}, which could be improved" Display --indent 4 --text "- umask (/etc/init.d/rc)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/init.d/rc could be more strict like 027" AddHP 0 2 fi else LogText "Result: file /etc/init.d/rc does not exist" fi # FreeBSD if [ -f /etc/login.conf ]; then FOUND=0 WEAK_UMASK=0 LogText "Result: file /etc/login.conf exists" FIND=$(${GREPBINARY} "umask" /etc/login.conf | ${SEDBINARY} 's/#.*//' | ${SEDBINARY} -E 's/^[[:cntrl:]]//' | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $2}' | ${AWKBINARY} -F= '{ if ($1=="umask") { print $2 }}') if [ ! "${FIND}" = "" ]; then for UMASK_VALUE in ${FIND}; do case ${UMASK_VALUE} in 027|0027|077|0077) LogText "Result: found umask value ${UMASK_VALUE}, which is fine" AddHP 2 2 FOUND=1 ;; *) AddHP 0 2 FOUND=1 WEAK_UMASK=1 LogText "Result: found umask value ${UMASK_VALUE}, which can be more strict" ;; esac done fi if [ ${FOUND} -eq 1 ]; then if [ ${WEAK_UMASK} -eq 0 ]; then Display --indent 4 --text "- umask (/etc/login.conf)" --result "${STATUS_OK}" --color GREEN else Display --indent 4 --text "- umask (/etc/login.conf)" --result "${STATUS_WEAK}" --color YELLOW ReportSuggestion "${TEST_NO}" "Umask in /etc/login.conf could be more strict like 027" fi else LogText "Result: no umask setting found in /etc/login.conf, which is unexpected" Display --indent 4 --text "- umask (/etc/login.conf)" --result "${STATUS_NONE}" --color YELLOW fi fi # /etc/init.d/rcS LogText "Test: Checking /etc/init.d/rcS" if [ -f /etc/init.d/rcS ]; then LogText "Result: file /etc/init.d/rcS exists" LogText "Test: Checking if script runs another script." FIND=$(${GREPBINARY} -i "^exec " /etc/init.d/rcS | ${AWKBINARY} '{ print $2 }') if [ "${FIND}" = "" ]; then FIND2=$(${GREPBINARY} -i "^UMASK" /etc/init.d/rcS | ${AWKBINARY} '{ print $2 }') if [ "${FIND2}" = "" ]; then LogText "Result: UMASK value is not configured (most likely it will have the default 022 value)" Display --indent 4 --text "- Checking umask (/etc/init.d/rcS)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/init.d/rcS could not be found and defaults usually to 022, which could be more strict like 027" AddHP 1 2 elif [ "${FIND2}" = "077" -o "${FIND2}" = "027" ]; then LogText "Result: umask is ${FIND2}, which is fine" Display --indent 4 --text "- umask (/etc/init.d/rcS)" --result "${STATUS_OK}" --color GREEN AddHP 2 2 else LogText "Result: found umask ${FIND2}, which could be improved" Display --indent 4 --text "- umask (/etc/init.d/rcS)" --result "${STATUS_SUGGESTION}" --color YELLOW ReportSuggestion "${TEST_NO}" "Default umask in /etc/init.d/rcS could be more strict like 027" AddHP 0 2 fi else # Improve check LogText "Result: exec line present in file, setting of umask not needed in this script" LogText "Output: ${FIND}" fi else LogText "Result: file /etc/init.d/rcS does not exist" fi fi # ################################################################################# # # Test : AUTH-9340 # Description : Solaris account locking Register --test-no AUTH-9340 --os Solaris --weight L --network NO --category security --description "Solaris account locking" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 if [ -f ${ROOTDIR}etc/security/policy.conf ]; then LogText "Result: found ${ROOTDIR}etc/security/policy.conf" FIND=$(${GREPBINARY} "^LOCK_AFTER_RETRIES" /etc/security/policy.conf) if [ ! "${FIND}" = "" ]; then FOUND=1 LogText "Result: account locking option set" LogText "Output: ${FIND}" AddHP 2 2 else LogText "Result: option LOCK_AFTER_RETRIES not set" AddHP 1 2 fi else LogText "Result: ${ROOTDIR}etc/security/policy.conf does not exist" fi # If policy.conf does not exist, we most likely deal with a Solaris version below 10 # and we proceed with checking the softer option RETRIES in /etc/default/login # which does not lock account, but discourages brute force password attacks. if [ ${FOUND} -eq 0 ]; then LogText "Test: checking ${ROOTDIR}etc/default/login" if [ -f ${ROOTDIR}etc/default/login ]; then LogText "Result: file ${ROOTDIR}etc/default/login exists" FIND=$(${GREPBINARY} "^RETRIES" ${ROOTDIR}etc/default/login) if [ -n "${FIND}" ]; then FOUND=1 LogText "Result: retries option configured" LogText "Output: ${FIND}" AddHP 2 2 else LogText "Result: retries option not configured" AddHP 1 2 fi else LogText "Result: file ${ROOTDIR}etc/default/login does not exist" fi fi if [ ${FOUND} -eq 1 ]; then Display --indent 2 --text "- Checking account locking" --result "${STATUS_ENABLED}" --color GREEN else Display --indent 2 --text "- Checking account locking" --result "${STATUS_NOT_ENABLED}" --color YELLOW fi fi # ################################################################################# # # Test : AUTH-9402 # Description : Query LDAP authentication support Register --test-no AUTH-9402 --weight L --network NO --category security --description "Query LDAP authentication support" if [ ${SKIPTEST} -eq 0 ]; then if [ -f ${ROOTDIR}etc/nsswitch.conf ]; then FIND=$(${GREPBINARY} -E "^passwd" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} "ldap") if [ "${FIND}" = "" ]; then LogText "Result: LDAP authentication not enabled" Display --indent 2 --text "- LDAP authentication support" --result "${STATUS_NOT_ENABLED}" --color WHITE else LogText "Result: LDAP authentication enabled" Display --indent 2 --text "- LDAP authentication support" --result "${STATUS_ENABLED}" --color GREEN LDAP_AUTH_ENABLED=1 fi else LogText "Result: /etc/nsswitch.conf not found" fi fi # ################################################################################# # # Test : AUTH-9406 # Description : Check LDAP servers in client configuration if [ ${LDAP_AUTH_ENABLED} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9406 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Query LDAP servers in client configuration" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: checking ldap.conf options" for FILE in ${LDAP_CONF_LOCATIONS}; do LogText "Test: checking ${FILE}" if [ -f ${FILE} ]; then LogText "Result: file ${FILE} exists, LDAP being used" LDAP_CLIENT_CONFIG_FILE="${FILE}" LogText "Test: checking LDAP servers in file ${FILE}" FIND=$(${GREPBINARY} -E "^host " ${FILE} | ${AWKBINARY} '{ print $2 }') for SERVER in ${FIND}; do Display --indent 6 --text "LDAP server: ${SERVER}" LogText "Result: found LDAP server ${SERVER}" Report "ldap_server[]=${SERVER}" done else LogText "Result: ${FILE} does NOT exist" fi done unset FILE FIND SERVER fi # ################################################################################# # # Test : AUTH-9408 # Description : Logging of failed login attempts Register --test-no AUTH-9408 --weight L --network NO --category security --description "Logging of failed login attempts" if [ ${SKIPTEST} -eq 0 ]; then if [ -f "${ROOTDIR}etc/pam.conf" -o -d "${ROOTDIR}etc/pam.d" ]; then FOUND_PAM_TALLY2=0 FOUND_TALLYLOG=0 FOUND_PAM_FAILLOCK=0 FOUND_FAILLOCKDIR=0 if [ -d "${ROOTDIR}var/run/faillock" ]; then FOUND_FAILLOCKDIR=1 LogText "Result: found ${ROOTDIR}var/run/faillock directory" elif [ -s "${ROOTDIR}var/log/tallylog" ]; then FOUND_TALLYLOG=1 LogText "Result: found ${ROOTDIR}var/log/tallylog with a size bigger than zero" else LogText "Result: did not find ${ROOTDIR}var/run/faillock directory or ${ROOTDIR}var/log/tallylog file on disk or its file size is zero bytes" fi # Determine if pam_faillock is available for D in $(GetReportData --key "pam_module\\\[\\\]"); do if ContainsString "pam_faillock" "${D}"; then LogText "Result: found pam_faillock module on disk" FOUND_PAM_FAILLOCK=1 fi done if [ ${FOUND_PAM_FAILLOCK} -eq 0 ]; then # Determine if pam_tally2 is available for D in $(GetReportData --key "pam_module\\\[\\\]"); do if ContainsString "pam_tally2" "${D}"; then LogText "Result: found pam_tally2 module on disk" FOUND_PAM_TALLY2=1 fi done fi if [ ${FOUND_PAM_FAILLOCK} -eq 1 -a ${FOUND_FAILLOCKDIR} -eq 1 ]; then LogText "Outcome: authentication failures are logged using pam_faillock" AUTH_FAILED_LOGINS_LOGGED=1 Report "auth_failed_logins_tooling[]=pam_faillock" elif [ ${FOUND_PAM_TALLY2} -eq 1 -a ${FOUND_TALLYLOG} -eq 1 ]; then LogText "Outcome: authentication failures are logged using pam_tally2" AUTH_FAILED_LOGINS_LOGGED=1 Report "auth_failed_logins_tooling[]=pam_tally2" else LogText "Outcome: it looks like pam_faillock or pam_tally2 is not configured to log failed login attempts" fi unset FOUND_PAM_TALLY2 FOUND_TALLYLOG FOUND_PAM_FAILLOCK FOUND_FAILLOCKDIR fi # Also check /etc/logins.defs, although its usage decreased over the years if [ -f ${ROOTDIR}etc/login.defs ]; then LogText "Test: Checking FAILLOG_ENAB option in ${ROOTDIR}etc/login.defs " FIND=$(${GREPBINARY} "^FAILLOG_ENAB" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1=="FAILLOG_ENAB") { print $2 } }') # Search for enabled status (yes), otherwise consider it to be disabled (e.g. empty, or other value) if [ "${FIND}" = "yes" ]; then AUTH_FAILED_LOGINS_LOGGED=1 Report "auth_failed_logins_tooling[]=/etc/login.defs" LogText "Result: FAILLOG_ENAB is set to 'yes'" LogText "Outcome: failed login attempts are logged in ${ROOTDIR}var/log/faillog" Display --indent 2 --text "- Logging failed login attempts" --result "${STATUS_ENABLED}" --color GREEN else LogText "Result: failed login attempts may not logged" Display --indent 2 --text "- Logging failed login attempts" --result "${STATUS_DISABLED}" --color YELLOW fi fi if [ ${AUTH_FAILED_LOGINS_LOGGED} -eq 1 ]; then AddHP 3 3 else AddHP 0 1 #ReportSuggestion "${TEST_NO}" "Configure failed login attempts to be logged using pam_tally2 or /etc/login.defs" fi fi # ################################################################################# # # Test : AUTH-9409 # Description : Check for doas file DOAS_FILE="" Register --test-no AUTH-9409 --os OpenBSD --weight L --network NO --category security --description "Checking /etc/doas.conf file" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 LogText "Test: checking presence /etc/doas.conf" if [ -f /etc/doas.conf ]; then DOAS_FILE=/etc/doas.conf FOUND=1 LogText "Result: file /etc/doas.conf found" else LogText "Result: file /etc/doas.conf not found" fi if [ ${FOUND} -eq 1 ]; then LogText "Result: /etc/doas.conf file found" Display --indent 2 --text "- doas file" --result "${STATUS_FOUND}" --color GREEN else LogText "Result: doas file NOT found" Display --indent 2 --text "- doas file" --result "${STATUS_NOT_FOUND}" --color YELLOW fi fi # ################################################################################# # # Test : AUTH-9410 # Description : Check for doas file permissions if [ -n "${DOAS_FILE}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no AUTH-9410 --os OpenBSD --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check /etc/doas.conf file permissions" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: checking /etc/doas.conf permissions" FIND=$(ls -l ${DOAS_FILE} | ${CUTBINARY} -c 2-10) LogText "Result: Found /etc/doas.conf file permissions: ${FIND}" case "${FIND}" in r[w-]-[r-][w-]---- ) LogText "Result: file /etc/doas.conf has correct permissions" Display --indent 4 --text "- Check doas file permissions" --result "${STATUS_OK}" --color GREEN ;; * ) LogText "Result: file has possibly unsafe file permissions" Display --indent 4 --text "- Check doas file permissions" --result "${STATUS_WARNING}" --color RED ;; esac fi # ################################################################################# # Report "auth_failed_logins_logged=${AUTH_FAILED_LOGINS_LOGGED}" Report "ldap_auth_enabled=${LDAP_AUTH_ENABLED}" Report "ldap_pam_enabled=${LDAP_PAM_ENABLED}" if [ -n "${LDAP_CLIENT_CONFIG_FILE}" ]; then Report "ldap_config_file=${LDAP_CLIENT_CONFIG_FILE}"; fi Report "password_min_days=${PASSWORD_MINIMUM_DAYS}" Report "password_max_days=${PASSWORD_MAXIMUM_DAYS}" WaitForKeyPress # #================================================================================ # Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
Save
cmd:
run