From c8af37c069313a3bad1d47e7bd33391e3a83e538 Mon Sep 17 00:00:00 2001 From: Capashenn Date: Mon, 25 Mar 2019 13:44:25 +0100 Subject: [PATCH 01/23] fix issues #666 #667 --- include/tests_homedirs | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/include/tests_homedirs b/include/tests_homedirs index 045a2753..6beadaa5 100644 --- a/include/tests_homedirs +++ b/include/tests_homedirs @@ -50,6 +50,65 @@ fi # ################################################################################# +# + # Test : HOME-9304 + # Description : Check if users' home directories permissions are 750 or more restrictive + Register --test-no HOME-9304 --weight L --network NO --category security --description "Check if users' home directories permissions are 750 or more restrictive" + if [ ${SKIPTEST} -eq 0 ]; then + # Check if users' home directories permissions are 750 or more restrictive + FOUND=0 + for LINE in $(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }'); do + USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) + DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) + if [ -d ${DIR} ]; then + WRITE_GROUP_PERM=$(ls -ld ${DIR} | ${CUTBINARY} -f1 -d" " | ${CUTBINARY} -c6) + OTHER_PERMS=$(ls -ld ${DIR} | ${CUTBINARY} -f1 -d" " | ${CUTBINARY} -c8-10) + if [ ! ${WRITE_GROUP_PERM} = "-" -o ! ${OTHER_PERMS} = "---" ]; then + LogText "Result: permissions of home directory ${DIR} of user ${USER} are not strict enough. Should be 750 or more restrictive. Change with: chmod 750 ${DIR}" + FOUND=1 + fi + fi + done + # Result + if [ ${FOUND} -eq 1 ]; then + Display --indent 2 --text "- Checking users' home directories permissions" --result "${STATUS_WARNING}" --color RED + ReportWarning ${TEST_NO} "Permissions of some users' home directories are not strict enough. Should be 750 or more restrictive." + else + Display --indent 2 --text "- Checking users' home directories permissions" --result "${STATUS_OK}" --color GREEN + LogText "Result: Ok, All users' home directories permissions are 750 or more restrictive" + fi + fi +# +################################################################################# +# + # Test : HOME-9306 + # Description : Check if users own their home directories + Register --test-no HOME-9306 --weight L --network NO --category security --description "Check if users own their home directories" + if [ ${SKIPTEST} -eq 0 ]; then + # Check if users own their home directories + FOUND=0 + for LINE in $(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }'); do + USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) + DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) + if [ -d ${DIR} ]; then + OWNER=$(ls -ld ${DIR} | awk -F" " '{ print $3 }') + if [ ! ${OWNER} = ${USER} ]; then + LogText "Result: The home directory ${DIR} of user ${USER} is owned by ${OWNER}. Change with: chown ${OWNER} ${DIR}" + FOUND=1 + fi + fi + done + # Result + if [ ${FOUND} -eq 1 ]; then + Display --indent 2 --text "- Checking users' home directories ownership" --result "${STATUS_WARNING}" --color RED + ReportWarning ${TEST_NO} "Owner of some users' home directories are not correctly set" + else + Display --indent 2 --text "- Checking users' home directories ownership" --result "${STATUS_OK}" --color GREEN + LogText "Result: Ok, All users own their home directories" + fi + fi +# +################################################################################# # # Test : HOME-9310 # Description : Check for suspicious shell history files From 06cdf6c50f7bac61afc6dc383716262e7c7d9838 Mon Sep 17 00:00:00 2001 From: Capashenn Date: Mon, 25 Mar 2019 14:46:27 +0100 Subject: [PATCH 02/23] fix issue #659 --- include/tests_kernel | 68 ++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/include/tests_kernel b/include/tests_kernel index f89177ce..66a80214 100644 --- a/include/tests_kernel +++ b/include/tests_kernel @@ -31,6 +31,7 @@ CPU_NX=0 LINUXCONFIGFILE="" LINUXCONFIGFILE_ZIPPED=0 + LIMITS_DIRECTORY="${ROOTDIR}etc/security/limits.d" # ################################################################################# # @@ -436,51 +437,56 @@ # Description : Checking core dumps configuration (Linux) Register --test-no KRNL-5820 --os Linux --weight L --network NO --category security --description "Checking core dumps configuration" if [ ${SKIPTEST} -eq 0 ]; then + # Limits option LogText "Test: Checking presence /etc/security/limits.conf" if [ -f /etc/security/limits.conf ]; then LogText "Result: file /etc/security/limits.conf exists" - LogText "Test: Checking if core dumps are disabled in /etc/security/limits.conf" - FIND1=$(${GREPBINARY} -v "^#" /etc/security/limits.conf | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="soft" && $3=="core" && $4=="1") { print "soft core enabled" } }') - FIND2=$(${GREPBINARY} -v "^#" /etc/security/limits.conf | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="hard" && $3=="core" && $4=="1") { print "hard core enabled" } }') - if [ "${FIND1}" = "soft core enabled" -o "${FIND2}" = "hard core enabled" ]; then - LogText "Result: core dumps (soft or hard) are enabled" - Display --indent 2 --text "- Checking core dumps configuration" --result "${STATUS_ENABLED}" --color YELLOW - ReportSuggestion "${TEST_NO}" "Check if core dumps need to be enabled on this system" - AddHP 1 2 - else + LogText "Test: Checking if core dumps are disabled in /etc/security/limits.conf and /etc/security/limits.d/*" + FIND1=$(${GREPBINARY} -r -v "^#" /etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="soft" && $3=="core" && $4=="0") { print "soft core disabled" } else if ($1=="*" && $2=="soft" && $3=="core" && $4!="0") { print "soft core enabled" } }') + FIND2=$(${GREPBINARY} -r -v "^#" /etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="hard" && $3=="core" && $4=="0") { print "hard core disabled" } else if ($1=="*" && $2=="hard" && $3=="core" && $4!="0") { print "hard core enabled" } }') + if [ "${FIND2}" = "hard core disabled" ]; then LogText "Result: core dumps (soft and hard) are both disabled" Display --indent 2 --text "- Checking core dumps configuration" --result "${STATUS_DISABLED}" --color GREEN CORE_DUMPS_DISABLED=1 AddHP 3 3 - fi - - # Sysctl option - LogText "Test: Checking sysctl value of fs.suid_dumpable" - FIND=$(${SYSCTLBINARY} fs.suid_dumpable 2> /dev/null | ${AWKBINARY} '{ if ($1=="fs.suid_dumpable") { print $3 } }') - if [ -z "${FIND}" ]; then - LogText "Result: sysctl key fs.suid_dumpable not found" + elif [ "${FIND1}" = "soft core enabled" -o "${FIND2}" = "hard core enabled" ]; then + LogText "Result: core dumps (soft or hard) are enabled" + Display --indent 2 --text "- Checking core dumps configuration" --result "${STATUS_ENABLED}" --color YELLOW + ReportSuggestion "${TEST_NO}" "Check if core dumps need to be enabled on this system" + AddHP 1 3 else - LogText "Result: value ${FIND} found" - fi - if [ "${FIND}" = "2" ]; then - LogText "Result: programs can dump core dump, but only readable by root (value 2, for debugging with file protection)" - Display --indent 4 --text "- Checking setuid core dumps configuration" --result PROTECTED --color GREEN - AddHP 1 1 - elif [ "${FIND}" = "1" ]; then - LogText "Result: all programs can perform core dumps (value 1, for debugging)" - Display --indent 2 --text "- Checking setuid core dumps configuration" --result DEBUG --color YELLOW - ReportSuggestion "${TEST_NO}" "Determine if all binaries need to be able to core dump" - AddHP 0 1 - else - LogText "Result: found default option, some programs can dump (not processes which need to change credentials)" - Display --indent 4 --text "- Checking setuid core dumps configuration" --result DEFAULT --color WHITE - AddHP 1 1 + LogText "Result: core dumps are not explicitly disabled" + Display --indent 2 --text "- Checking core dumps configuration" --result "${STATUS_NOT_FOUND}" --color WHITE + ReportSuggestion "${TEST_NO}" "If not required, consider explicit disabling of core dump in /etc/security/limits.conf file" + AddHP 2 3 fi else LogText "Result: file /etc/security/limits.conf does not exist, skipping test" fi # TODO: Check ulimit settings in /etc/profile and /etc/profile.d + # Sysctl option + LogText "Test: Checking sysctl value of fs.suid_dumpable" + FIND=$(${SYSCTLBINARY} fs.suid_dumpable 2> /dev/null | ${AWKBINARY} '{ if ($1=="fs.suid_dumpable") { print $3 } }') + if [ -z "${FIND}" ]; then + LogText "Result: sysctl key fs.suid_dumpable not found" + else + LogText "Result: value ${FIND} found" + fi + if [ "${FIND}" = "2" ]; then + LogText "Result: programs can dump core dump, but only readable by root (value 2, for debugging with file protection)" + Display --indent 4 --text "- Checking setuid core dumps configuration" --result PROTECTED --color GREEN + AddHP 1 1 + elif [ "${FIND}" = "1" ]; then + LogText "Result: all programs can perform core dumps (value 1, for debugging)" + Display --indent 2 --text "- Checking setuid core dumps configuration" --result DEBUG --color YELLOW + ReportSuggestion "${TEST_NO}" "Determine if all binaries need to be able to core dump" + AddHP 0 1 + else + LogText "Result: found default option, some programs can dump (not processes which need to change credentials)" + Display --indent 4 --text "- Checking setuid core dumps configuration" --result DEFAULT --color WHITE + AddHP 1 1 + fi fi # ################################################################################# From 295a2699d3fa18c06d4191725254b2b0a94ba463 Mon Sep 17 00:00:00 2001 From: Capashenn Date: Fri, 29 Mar 2019 16:34:01 +0100 Subject: [PATCH 03/23] bugfix HOME-9304 HOME-9306 --- include/tests_homedirs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/tests_homedirs b/include/tests_homedirs index 6beadaa5..1c850105 100644 --- a/include/tests_homedirs +++ b/include/tests_homedirs @@ -57,7 +57,7 @@ if [ ${SKIPTEST} -eq 0 ]; then # Check if users' home directories permissions are 750 or more restrictive FOUND=0 - for LINE in $(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }'); do + for LINE in "$(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) if [ -d ${DIR} ]; then @@ -87,13 +87,13 @@ if [ ${SKIPTEST} -eq 0 ]; then # Check if users own their home directories FOUND=0 - for LINE in $(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }'); do + for LINE in "$(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) if [ -d ${DIR} ]; then OWNER=$(ls -ld ${DIR} | awk -F" " '{ print $3 }') if [ ! ${OWNER} = ${USER} ]; then - LogText "Result: The home directory ${DIR} of user ${USER} is owned by ${OWNER}. Change with: chown ${OWNER} ${DIR}" + LogText "Result: The home directory ${DIR} of user ${USER} is owned by ${OWNER}. Change with: chown ${USER} ${DIR}" FOUND=1 fi fi From 26fca99c40f6aeaca7a5e38db61fc197383d6b36 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 11:49:14 +0200 Subject: [PATCH 04/23] Textual changes --- include/functions | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/functions b/include/functions index 16cef804..794abcc4 100644 --- a/include/functions +++ b/include/functions @@ -2742,9 +2742,8 @@ fi # Check file permissions if [ ! -f "$1" ]; then - LogText "Fatal error: file $1 does not exist. Quitting." - echo "Fatal error: file $1 does not exist" - ExitFatal + LogText "Fatal error: file $1 does not exist." + ExitFatal "Fatal error: file $1 does not exist" else PERMS=$(ls -l $1) @@ -2771,21 +2770,22 @@ # Owner permissions OWNER_PERMS=$(echo ${PERMS} | cut -c2-4) if [ ! "${OWNER_PERMS}" = "rw-" -a ! "${OWNER_PERMS}" = "r--" ]; then - echo "Fatal error: permissions of file $1 are not strict enough. Access to 'owner' should be read-write, or read. Change with: chmod 600 $1" + echo "Fatal error: permissions of file $1 are not strict enough. Access to 'owner' should be read-write, or read. Change with: chmod u=rw $1" ExitFatal fi - # Owner permissions + # Group permissions + # TODO - harden this even more by setting default to read-only for group (like 'other') GROUP_PERMS=$(echo ${PERMS} | cut -c5-7) if [ ! "${GROUP_PERMS}" = "rw-" -a ! "${GROUP_PERMS}" = "r--" -a ! "${GROUP_PERMS}" = "---" ]; then - echo "Fatal error: permissions of file $1 are not strict enough. Access to 'group' should be read-write, read, or none. Change with: chmod 600 $1" + echo "Fatal error: permissions of file $1 are not strict enough. Access to 'group' should be read-write, read, or none. Change with: chmod g=r $1" ExitFatal fi # Other permissions OTHER_PERMS=$(echo ${PERMS} | cut -c8-10) if [ ! "${OTHER_PERMS}" = "---" -a ! "${OTHER_PERMS}" = "r--" ]; then - echo "Fatal error: permissions of file $1 are not strict enough. Access to 'other' should be denied or read-only. Change with: chmod 600 $1" + echo "Fatal error: permissions of file $1 are not strict enough. Access to 'other' should be denied or read-only. Change with: chmod o=r $1" ExitFatal fi # Set PERMS_OK to 1 if no fatal errors occurred From 34f306eb0bc5502535ca85f5700fa083ab6c9443 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 11:50:02 +0200 Subject: [PATCH 05/23] Internal reorganization --- include/consts | 1 - lynis | 143 +++++++++++++++++++++++++++---------------------- 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/include/consts b/include/consts index 67a18733..343567df 100644 --- a/include/consts +++ b/include/consts @@ -327,7 +327,6 @@ unset LANG HPTOTAL=0 # Maximum number of hardening points LOG_INCORRECT_OS=1 # Log tests with incorrect OS NEVERBREAK=0 # Don't wait for user input - PENTESTINGMODE=0 # Try tests without root privileges QUICKMODE=1 # Don't wait for user input QUIET=0 # Show normal messages and warnings as well SKIPLOGTEST=0 # Skip logging for one test diff --git a/lynis b/lynis index 0914f9c4..1324b4d5 100755 --- a/lynis +++ b/lynis @@ -21,27 +21,29 @@ # Lynis is an automated auditing tool for Unix based operating systems. # ################################################################################# +# + # In Solaris /bin/sh is not POSIX, but /usr/xpg4/bin/sh is. + # Switch to /usr/xpg4/bin/sh if it exists and we are not already running it. + if [ "$(uname)" = "SunOS" ]; then + test "$_" != "/usr/xpg4/bin/sh" && test -f /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh "$0" "$@" + fi +# +################################################################################# # # Code quality: don't allow using undefined variables + # Notes: $_ may be empty on FreeBSD set -o nounset # ################################################################################# # - # In Solaris /bin/sh is not POSIX, but /usr/xpg4/bin/sh is. - # Switch to /usr/xpg4/bin/sh if it exists and we are not already running it. - test "$_" != "/usr/xpg4/bin/sh" && test -f /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh "$0" "$@" -# -################################################################################# -# - # Program information PROGRAM_NAME="Lynis" PROGRAM_AUTHOR="CISOfy" PROGRAM_AUTHOR_CONTACT="lynis-dev@cisofy.com" # Version details - PROGRAM_RELEASE_DATE="2019-06-29" - PROGRAM_RELEASE_TIMESTAMP=1561383761 + PROGRAM_RELEASE_DATE="2019-07-14" + PROGRAM_RELEASE_TIMESTAMP=1563094548 PROGRAM_RELEASE_TYPE="dev" # dev or final PROGRAM_VERSION="3.0.0" @@ -58,7 +60,6 @@ REPORT_version_major="1"; REPORT_version_minor="0" REPORT_version="${REPORT_version_major}.${REPORT_version_minor}" - DISPLAY_LANG="${LANG}" # required by function Display to deal with multi-bytes characters. # ################################################################################# @@ -74,53 +75,31 @@ WORKDIR=$(pwd) # Test from which directories we can use all functions and tests - - INCLUDEDIR="" # Set default include directory to none - tINCLUDE_TARGETS="/usr/local/include/lynis /usr/local/lynis/include /usr/share/lynis/include ./include" # Default paths to check (CWD as last option, in case we run from standalone) - for I in ${tINCLUDE_TARGETS}; do - if [ "${I}" = "./include" ]; then - if [ -d "${WORKDIR}/include" ]; then INCLUDEDIR="${WORKDIR}/include"; fi - elif [ -d ${I} -a -z "${INCLUDEDIR}" ]; then - INCLUDEDIR=${I} - fi - done + INCLUDEDIR="" + tINCLUDE_TARGETS="/usr/local/include/lynis /usr/local/lynis/include /usr/share/lynis/include ./include" # Default paths to check (CWD as last option, in case we run from standalone) + for I in ${tINCLUDE_TARGETS}; do + if [ "${I}" = "./include" ]; then + if [ -d "${WORKDIR}/include" ]; then INCLUDEDIR="${WORKDIR}/include"; fi + elif [ -d ${I} -a -z "${INCLUDEDIR}" ]; then + INCLUDEDIR=${I} + fi + done # Drop out if our include directory can't be found - if [ -z "${INCLUDEDIR}" ]; then - printf "%s" " -Fatal error: can't find include directory -Make sure to execute ${PROGRAM_NAME} from untarred directory or check your installation." - exit 1 - fi + if [ -z "${INCLUDEDIR}" ]; then + printf "%s" "\nFatal error: can't find include directory\nMake sure to execute ${PROGRAM_NAME} from untarred directory or check your installation." + exit 1 + fi # Test for database directory - - DBDIR=""; tDB_TARGETS="/usr/local/share/lynis/db /usr/local/lynis/db /usr/share/lynis/db ./db" - for I in ${tDB_TARGETS}; do - if [ "${I}" = "./db" ]; then - if [ -d "${WORKDIR}/db" ]; then DBDIR="${WORKDIR}/db"; fi - elif [ -d ${I} -a -z "${DBDIR}" ]; then - DBDIR="${I}" - fi - done - - # Import translations. First import English to prefill all texts - if [ ! -f ${DBDIR}/languages/en ]; then - echo "Could not find languages directory (file: ${DBDIR}/languages/en)" - exit 1 - else - . ${DBDIR}/languages/en - fi - - # Auto detection of language based on locale (first two characters). Set to English when nothing found. - if [ -x "$(command -v locale 2> /dev/null)" ]; then - LANGUAGE=$(locale | egrep "^LANG=" | cut -d= -f2 | cut -d_ -f1 | egrep "^[a-z]{2}$") - fi - if [ -z "${LANGUAGE}" ]; then - #Debug "Result: no (valid) language found, setting to default language (en)" - LANGUAGE="en" - fi - + DBDIR=""; tDB_TARGETS="/usr/local/share/lynis/db /usr/local/lynis/db /usr/share/lynis/db ./db" + for I in ${tDB_TARGETS}; do + if [ "${I}" = "./db" ]; then + if [ -d "${WORKDIR}/db" ]; then DBDIR="${WORKDIR}/db"; fi + elif [ -d ${I} -a -z "${DBDIR}" ]; then + DBDIR="${I}" + fi + done # ################################################################################# # @@ -128,7 +107,7 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta # Check user to determine file permissions later on. If we encounter Solaris, use related id binary instead if [ -x /usr/xpg4/bin/id ]; then MYID=$(/usr/xpg4/bin/id -u 2> /dev/null) - elif [ $(uname) = "SunOS" ]; then + elif [ "$(uname)" = "SunOS" ]; then MYID=$(id | tr '=' ' ' | tr '(' ' ' | awk '{ print $2 }' 2> /dev/null) else MYID=$(id -u 2> /dev/null) @@ -137,10 +116,21 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta # ################################################################################# # -# Consts (bin paths, text strings, colors) +# Set basic values and test permissions of the files to include, such as: +# - consts: bin paths, text strings, colors +# - functions: function library # ################################################################################# # + # Determine if we are root (UID = 0) + if [ ${MYID} -eq 0 ]; then + PRIVILEGED=1 + PENTESTINGMODE=0 + else + # Set to pentesting mode if scan is with root privileges + PENTESTINGMODE=1 + fi + # Perform a basic check for permissions. After including functions, using SafePerms() IGNORE_FILE_PERMISSION_ISSUES=0 @@ -204,6 +194,41 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta # ################################################################################# # +# Language settings +# +################################################################################# +# + # Auto detection of language based on shell LANG variable. This is required by the Display() function to deal with multi-bytes characters. + DISPLAY_LANG="${LANG:-}" + # Try locale command if shell variable had no value + if [ -z "${DISPLAY_LANG}" ]; then + DISPLAY_LANG=$(locale | egrep "^LANG=" | cut -d= -f2) + fi + + # Extract the short notation of the language (first two characters). + if [ -x "$(command -v locale 2> /dev/null)" ]; then + LANGUAGE=$(locale | egrep "^LANG=" | cut -d= -f2 | cut -d_ -f1 | egrep "^[a-z]{2}$") + fi + + # Set default language: 'en' (English) if no value is set + if [ -z "${LANGUAGE}" ]; then + LANGUAGE="en" + fi + + # Import translations. First import English to prefill all texts + if [ -f ${DBDIR}/languages/en ]; then + if SafeFile "${DBDIR}/languages/en"; then + . ${DBDIR}/languages/en + else + ExitFatal "Incorrect ownership or permissions of language file (${DBDIR}/languages/en)" + fi + else + echo "Could not find languages directory (file: ${DBDIR}/languages/en)" + exit 1 + fi +# +################################################################################# +# # Traps # ################################################################################# @@ -222,14 +247,6 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta SafePerms ${INCLUDEDIR}/parameters . ${INCLUDEDIR}/parameters - # Now determine if we are root (UID = 0) - if [ ${MYID} -eq 0 ]; then - PRIVILEGED=1 - else - Debug "Starting Lynis non-privileged" - # Implied pentesting mode if not performed by root user - PENTESTINGMODE=1 - fi # Disable logging if no alternative was provided if [ ${PRIVILEGED} -eq 0 ]; then From 4829ae97221336f10ef2369b6cbf7929a62a8fb8 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 11:57:44 +0200 Subject: [PATCH 06/23] Long format for od does not exist on BSD --- include/profiles | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/profiles b/include/profiles index f8935ece..ad5e6b07 100644 --- a/include/profiles +++ b/include/profiles @@ -35,10 +35,8 @@ # Show deprecation message for old config entries FOUND=0 - #DATA=$(egrep "^config:" ${PROFILE} | od --address-radix=none -t a | sed 's/ /!space!/g') - #if ! IsEmpty "${DATA}"; then FOUND=1; fi - # Items such as 'apache:' - DATA=$(egrep "^[a-z-]{1,}:" ${PROFILE} | od --address-radix=none -t a | sed 's/ /!space!/g') + # Items such as 'config:' and 'apache:' + DATA=$(egrep "^[a-z-]{1,}:" ${PROFILE} | od -An -ta | sed 's/ /!space!/g') # od -An (no file offset), -ta (named character, to be on safe side) if ! IsEmpty "${DATA}"; then FOUND=1; fi if [ ${FOUND} -eq 1 ]; then @@ -49,7 +47,7 @@ fi # Security check for unexpected and possibly harmful escape characters - DATA=$(grep -v '^$\|^ \|^#\|^config:' ${PROFILE} | tr -d '[:alnum:]/\[\]\(\)\-_\|,\.:;= \n\r' | od --address-radix=none -t a | sed 's/ /!space!/g') + DATA=$(grep -v '^$\|^ \|^#\|^config:' ${PROFILE} | tr -d '[:alnum:]/\[\]\(\)\-_\|,\.:;= \n\r' | od -An -ta | sed 's/ /!space!/g') if ! IsEmpty "${DATA}"; then DisplayWarning "Your profile '${PROFILE}' contains unexpected characters. See the log file for more information." LogText "Found unexpected or possibly harmful characters in the profile. See output below." From ba32b1a001b703fe99fcf74da80816ac31245a74 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 12:18:05 +0200 Subject: [PATCH 07/23] Use xxd or hexdump, depending on OS --- include/helper_generate | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/helper_generate b/include/helper_generate index 31dba7ec..30044705 100644 --- a/include/helper_generate +++ b/include/helper_generate @@ -43,8 +43,18 @@ if [ $# -gt 0 ]; then fi # Generate random host IDs - HOSTID=$(head -c20 < /dev/urandom | xxd -c 20 -p) - HOSTID2=$(head -c32 < /dev/urandom | xxd -c 32 -p) + case "${OS}" in + "AIX") + # hexdump does not exist on AIX + HOSTID=$(head -c20 < /dev/urandom | xxd -c 20 -p) + HOSTID2=$(head -c32 < /dev/urandom | xxd -c 32 -p) + ;; + *) + # xxd does not exist on FreeBSD + HOSTID=$(head -c20 < /dev/urandom | hexdump -ve '"%.2x"') + HOSTID2=$(head -c32 < /dev/urandom | hexdump -ve '"%.2x"') + ;; + esac ${ECHOCMD} "Generated host identifiers" ${ECHOCMD} "- hostid: ${HOSTID}" From 96434508d40fe1d86f67874682645511b739b6ed Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 12:18:22 +0200 Subject: [PATCH 08/23] Disable testing for other tools, as xxd is not present on all systems by default --- include/binaries | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/binaries b/include/binaries index d894caf9..0fbefe46 100644 --- a/include/binaries +++ b/include/binaries @@ -304,12 +304,11 @@ [ "${WCBINARY:-}" ] || ExitFatal "wc binary not found" # Test a few other tools that we did not specifically define (yet) - TOOLS="xxd" - for T in ${TOOLS}; do - DATA=$(type ${T}) - if [ $? -gt 0 ]; then ExitFatal "${T} binary not found"; fi - done - + #TOOLS="xxd" + #for T in ${TOOLS}; do + # DATA=$(type ${T}) + # if [ $? -gt 0 ]; then ExitFatal "${T} binary not found"; fi + #done else LogText "Result: checking of binaries skipped in this mode" From 3f042353535e12972449c06a8193ebfd467349f8 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:06:23 +0200 Subject: [PATCH 09/23] [INSE-8116] added rsync service --- include/tests_insecure_services | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/include/tests_insecure_services b/include/tests_insecure_services index 841189d8..0560a3ea 100644 --- a/include/tests_insecure_services +++ b/include/tests_insecure_services @@ -213,7 +213,7 @@ if [ ${SKIPTEST} -eq 0 ]; then XINETD_INSECURE_SERVICE_FOUND=0 - ITEMS="chargen chargen-dgram chargen-stream daytime daytime-dgram daytime-stream discard discard-dgram discard-stream echo echo-dgram echo-stream time time-dgram time-stream ntalk rexec rlogin rsh talk telnet tftp" + ITEMS="chargen chargen-dgram chargen-stream daytime daytime-dgram daytime-stream discard discard-dgram discard-stream echo echo-dgram echo-stream time time-dgram time-stream ntalk rexec rlogin rsh rsync talk telnet tftp" for SERVICE in ${ITEMS}; do LogText "Test: checking service ${SERVICE}" @@ -246,26 +246,6 @@ fi # ################################################################################# -# - # Test : INSE-8150 - # Description : Check for rsync enabled via xinetd - #RSYNC_XINETD_CONFIG_FILE="${XINETD_CONFIG_DIR}/rsync" - #if [ ${XINETD_ACTIVE} -eq 1 -a -f ${RSYNC_XINETD_CONFIG_FILE} ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi - #Register --test-no INSE-8150 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check for rsync via xinetd" - #if [ ${SKIPTEST} -eq 0 ]; then - # LogText "Test: checking rsync presence in xinetd configuration" - # FIND=$(${GREPBINARY} "disable\s*=\s*no" ${RSYNC_XINETD_CONFIG_FILE}) - # if [ "${FIND}" = "" ]; then - # LogText "Result: rsync not enabled in ${RSYNC_XINETD_CONFIG_FILE}" - # Display --indent 6 --text "- Checking xinetd (rsync)" --result "${STATUS_DISABLED}" --color GREEN - # else - # LogText "Result: rsync enabled in ${RSYNC_XINETD_CONFIG_FILE}" - # Display --indent 6 --text "- Checking xinetd (rsync)" --result "${STATUS_ENABLED}" --color RED - # ReportSuggestion "${TEST_NO}" "Disable rsync in xinetd configuration" - # fi - #fi -# -################################################################################# # # Test : INSE-8200 # Description : Check if tcp_wrappers is installed when inetd/xinetd is active From 819f310750700988e70b9d791d3f4e0b2f3b730c Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:06:53 +0200 Subject: [PATCH 10/23] Updated log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1430528e..21966be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ measures to further tighten any possible misuse. - Security: the 'nounset' (set -u) parameter is now activated by default - Use only locations from PATH environment variable, unless it is not defined - Show 'lynis generate hostids' when they are missing +- INSE-8116 - added rsync service - NAME-4408 - corrected Report function call - NETW-3032 - small rewrite of test and extended with addrwatch - PROC-3602 - allow different root directory From 93e311e52e9c5c2671e0e3030fb4fd9634d9ded6 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:13:02 +0200 Subject: [PATCH 11/23] Added INSE-8314 and INSE-8316 for NIS client and server --- include/tests_insecure_services | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/include/tests_insecure_services b/include/tests_insecure_services index 0560a3ea..a52037a1 100644 --- a/include/tests_insecure_services +++ b/include/tests_insecure_services @@ -392,6 +392,57 @@ Display --indent 2 --text "- Installed telnet server package" --result "${STATUS_NOT_FOUND}" --color GREEN fi fi + +# +################################################################################# +# + # Test : INSE-8314 + # Description : Check if NIS client is installed + Register --test-no INSE-8314 --weight L --network NO --category security --description "Check if NIS client is installed" + if [ ${SKIPTEST} -eq 0 ]; then + FOUND="" + LogText "Test: Checking if NIS client is installed" + PACKAGES="nis ypbind" + for PACKAGE in ${PACKAGES}; do + PackageIsInstalled "${PACKAGE}" + if [ $? -eq 0 ]; then + FOUND="${PACKAGE}" + fi + done + if [ ${FOUND} ]; then + LogText "Result: NIS client is installed" + Display --indent 2 --text "- Checking NIS client installation" --result "${STATUS_SUGGESTION}" --color YELLOW + ReportSuggestion ${TEST_NO} "NIS client should be removed as it contains numerous security exposures and have been replaced with the more secure SSH package" + else + LogText "Result: NIS client is NOT installed" + Display --indent 2 --text "- Checking NIS client installation" --result "${STATUS_OK}" --color GREEN + fi + fi +# +################################################################################# +# + # Test : INSE-8316 + # Description : Check if NIS server is installed + Register --test-no INSE-8316 --weight L --network NO --category security --description "Check if NIS server is installed" + if [ ${SKIPTEST} -eq 0 ]; then + FOUND="" + LogText "Test: Checking if NIS server is installed" + PACKAGES="nis ypserv" + for PACKAGE in ${PACKAGES}; do + PackageIsInstalled "${PACKAGE}" + if [ $? -eq 0 ]; then + FOUND="${PACKAGE}" + fi + done + if [ ${FOUND} ]; then + LogText "Result: NIS server is installed" + Display --indent 2 --text "- Checking NIS server installation" --result "${STATUS_SUGGESTION}" --color YELLOW + ReportSuggestion ${TEST_NO} "Removing the ${FOUND} package decreases the risk of the accidental (or intentional) activation of NIS or NIS+ services" + else + LogText "Result: NIS server is NOT installed" + Display --indent 2 --text "- Checking NIS server installation" --result "${STATUS_OK}" --color GREEN + fi + fi # ################################################################################# # From ceb9ea193da6cba11f5cee37f05066afbbba4150 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:16:48 +0200 Subject: [PATCH 12/23] Renamed INSE-8342 to INSE-8304 --- include/tests_insecure_services | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/tests_insecure_services b/include/tests_insecure_services index a52037a1..c446705f 100644 --- a/include/tests_insecure_services +++ b/include/tests_insecure_services @@ -328,7 +328,7 @@ # # Test : INSE-8304 # Description : Check if rsh server is installed - Register --test-no INSE-8342 --weight L --network NO --category security --description "Check if rsh server is installed" + Register --test-no INSE-8304 --weight L --network NO --category security --description "Check if rsh server is installed" if [ ${SKIPTEST} -eq 0 ]; then # Check if rsh server is installed LogText "Test: Checking if rsh server is installed" From 7d33b59b0c21f1713011968e90914f390b0083ab Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:19:11 +0200 Subject: [PATCH 13/23] Added tests --- db/tests.db | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/tests.db b/db/tests.db index cd978c50..56faba09 100644 --- a/db/tests.db +++ b/db/tests.db @@ -181,6 +181,10 @@ INSE-8116:test:security:insecure_services::Insecure services enabled via xinetd: INSE-8200:test:security:insecure_services::Usage of TCP wrappers: INSE-8300:test:security:insecure_services::Presence of rsh client: INSE-8302:test:security:insecure_services::Presence of rsh server: +INSE-8310:test:security:insecure_services::Presence of telnet client: +INSE-8312:test:security:insecure_services::Presence of telnet server: +INSE-8314:test:security:insecure_services::Presence of NIS client: +INSE-8316:test:security:insecure_services::Presence of NIS server: KRNL-5622:test:security:kernel:Linux:Determine Linux default run level: KRNL-5677:test:security:kernel:Linux:Check CPU options and support: KRNL-5695:test:security:kernel:Linux:Determine Linux kernel version and release number: From ea67b779c7c2b0161bbee38966669de57a453d01 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:19:18 +0200 Subject: [PATCH 14/23] Updated log --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21966be2..63f26f84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,9 @@ measures to further tighten any possible misuse. - New profile option: disable-plugin - disables a single plugin - New profile option: ssl-certificate-paths-to-ignore - ignore a path - New test: CRYP-7930 - disk or file system encryption testing -- New test: PROC-3802 - Check presence of prelink tooling +- New test: INSE-8314 - test for NIS client +- New test: INSE-8316 - test for NIS server +- New test: PROC-3802 - check presence of prelink tooling - New report key: openssh_daemon_running - New command: lynis generate systemd-units - Measure timing of tests and report slow tests (10+ seconds) @@ -42,6 +44,7 @@ measures to further tighten any possible misuse. - Use only locations from PATH environment variable, unless it is not defined - Show 'lynis generate hostids' when they are missing - INSE-8116 - added rsync service +- INSE-8342 - renamed to INSE-8304 - NAME-4408 - corrected Report function call - NETW-3032 - small rewrite of test and extended with addrwatch - PROC-3602 - allow different root directory From 4b68c22f306e62d64b1ffc78eac91646c5210c3d Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:27:08 +0200 Subject: [PATCH 15/23] Use relative paths --- include/tests_homedirs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/tests_homedirs b/include/tests_homedirs index 1c850105..9570816b 100644 --- a/include/tests_homedirs +++ b/include/tests_homedirs @@ -37,8 +37,8 @@ Register --test-no HOME-9302 --weight L --network NO --category security --description "Create list with home directories" if [ ${SKIPTEST} -eq 0 ]; then # Read sixth field of /etc/passwd - LogText "Test: query /etc/passwd to obtain home directories" - FIND=$(${AWKBINARY} -F: '{ if ($1 !~ "#") print $6 }' /etc/passwd | ${SORTBINARY} -u) + LogText "Test: query ${ROOTDIR}etc/passwd to obtain home directories" + FIND=$(${AWKBINARY} -F: '{ if ($1 !~ "#") print $6 }' ${ROOTDIR}etc/passwd | ${SORTBINARY} -u) for I in ${FIND}; do if [ -d ${I} ]; then LogText "Result: found home directory: ${I} (directory exists)" @@ -57,7 +57,7 @@ if [ ${SKIPTEST} -eq 0 ]; then # Check if users' home directories permissions are 750 or more restrictive FOUND=0 - for LINE in "$(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do + for LINE in "$(${CAT_BINARY} ${ROOTDIR}etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) if [ -d ${DIR} ]; then @@ -69,7 +69,7 @@ fi fi done - # Result + if [ ${FOUND} -eq 1 ]; then Display --indent 2 --text "- Checking users' home directories permissions" --result "${STATUS_WARNING}" --color RED ReportWarning ${TEST_NO} "Permissions of some users' home directories are not strict enough. Should be 750 or more restrictive." @@ -87,7 +87,7 @@ if [ ${SKIPTEST} -eq 0 ]; then # Check if users own their home directories FOUND=0 - for LINE in "$(${CAT_BINARY} /etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do + for LINE in "$(${CAT_BINARY} ${ROOTDIR}etc/passwd | ${EGREPBINARY} -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !="/sbin/nologin" && $7 != "/bin/false") { print }')"; do USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1) DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6) if [ -d ${DIR} ]; then @@ -98,7 +98,7 @@ fi fi done - # Result + if [ ${FOUND} -eq 1 ]; then Display --indent 2 --text "- Checking users' home directories ownership" --result "${STATUS_WARNING}" --color RED ReportWarning ${TEST_NO} "Owner of some users' home directories are not correctly set" From b025b3301a85fd13f554c41a3d9c5105bb0b542f Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:36:45 +0200 Subject: [PATCH 16/23] Define relative or absolute path, depending on directory/file or being a binary --- include/tests_kernel | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/include/tests_kernel b/include/tests_kernel index 66a80214..7a542c3d 100644 --- a/include/tests_kernel +++ b/include/tests_kernel @@ -235,18 +235,18 @@ # Description : Checking for available Linux kernel configuration file in /boot Register --test-no KRNL-5728 --os Linux --weight L --network NO --category security --description "Checking Linux kernel config" if [ ${SKIPTEST} -eq 0 ]; then - CHECKFILE="/boot/config-$(uname -r)" + CHECKFILE="${ROOTDIR}boot/config-$(uname -r)" if [ -f ${CHECKFILE} ]; then LINUXCONFIGFILE="${CHECKFILE}" LogText "Result: found config (${LINUXCONFIGFILE})" Display --indent 2 --text "- Checking Linux kernel configuration file" --result "${STATUS_FOUND}" --color GREEN - elif [ -f /proc/config.gz ]; then + elif [ -f ${ROOTDIR}proc/config.gz ]; then LINUXCONFIGFILE="${CHECKFILE}" LINUXCONFIGFILE_ZIPPED=1 - LogText "Result: found config: /proc/config.gz (compressed)" + LogText "Result: found config: ${ROOTDIR}proc/config.gz (compressed)" Display --indent 2 --text "- Checking Linux kernel configuration file" --result "${STATUS_FOUND}" --color GREEN else - LogText "Result: no Linux kernel configuration file found in /boot" + LogText "Result: no Linux kernel configuration file found in ${ROOTDIR}boot" Display --indent 2 --text "- Checking Linux kernel configuration file" --result "${STATUS_NOT_FOUND}" --color WHITE fi if HasData "${LINUXCONFIGFILE}"; then @@ -267,15 +267,15 @@ Register --test-no KRNL-5730 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking disk I/O kernel scheduler" if [ ${SKIPTEST} -eq 0 ]; then if [ ${LINUXCONFIGFILE_ZIPPED} -eq 1 ]; then GREPTOOL="${ZGREPBINARY}"; else GREPTOOL="${GREPBINARY}"; fi - if [ ! "${GREPTOOL}" = "" ]; then + if [ -n "${GREPTOOL}" ]; then LogText "Test: Checking the default I/O kernel scheduler" LINUX_KERNEL_IOSCHED=$(${GREPTOOL} "CONFIG_DEFAULT_IOSCHED" ${LINUXCONFIGFILE} | ${AWKBINARY} -F= '{ print $2 }' | ${SEDBINARY} s/\"//g) - if [ ! "${LINUX_KERNEL_IOSCHED}" = "" ]; then + if [ -n "${LINUX_KERNEL_IOSCHED}" ]; then LogText "Result: found IO scheduler '${LINUX_KERNEL_IOSCHED}'" Display --indent 2 --text "- Checking default I/O kernel scheduler" --result "${STATUS_FOUND}" --color GREEN Report "linux_kernel_io_scheduler[]=${LINUX_KERNEL_IOSCHED}" else - LogText "Result: no default i/o kernel scheduler found" + LogText "Result: no default I/O kernel scheduler found" Display --indent 2 --text "- Checking default I/O kernel scheduler" --result "${STATUS_NOT_FOUND}" --color WHITE fi else @@ -323,8 +323,8 @@ LogText "Test: Active kernel modules (KLDs)" LogText "Description: View all active kernel modules (including kernel)" LogText "Test: Checking modules" - if [ -f ${ROOTDIR}sbin/kldstat ]; then - FIND=$(${ROOTDIR}sbin/kldstat | ${GREPBINARY} -v 'Name' | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f6) + if [ -x /sbin/kldstat ]; then + FIND=$(/sbin/kldstat | ${GREPBINARY} -v 'Name' | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f6) if [ $? -eq 0 ]; then LogText "Loaded modules according kldstat:" COUNT=0 @@ -340,7 +340,7 @@ fi else echo "[ ${WHITE}SKIPPED${NORMAL} ]" - LogText "Result: no results, can NOT find ${ROOTDIR}sbin/kldstat" + LogText "Result: no results, can NOT find /sbin/kldstat" fi fi # @@ -438,12 +438,12 @@ Register --test-no KRNL-5820 --os Linux --weight L --network NO --category security --description "Checking core dumps configuration" if [ ${SKIPTEST} -eq 0 ]; then # Limits option - LogText "Test: Checking presence /etc/security/limits.conf" - if [ -f /etc/security/limits.conf ]; then - LogText "Result: file /etc/security/limits.conf exists" - LogText "Test: Checking if core dumps are disabled in /etc/security/limits.conf and /etc/security/limits.d/*" - FIND1=$(${GREPBINARY} -r -v "^#" /etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="soft" && $3=="core" && $4=="0") { print "soft core disabled" } else if ($1=="*" && $2=="soft" && $3=="core" && $4!="0") { print "soft core enabled" } }') - FIND2=$(${GREPBINARY} -r -v "^#" /etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="hard" && $3=="core" && $4=="0") { print "hard core disabled" } else if ($1=="*" && $2=="hard" && $3=="core" && $4!="0") { print "hard core enabled" } }') + LogText "Test: Checking presence ${ROOTDIR}etc/security/limits.conf" + if [ -f ${ROOTDIR}etc/security/limits.conf ]; then + LogText "Result: file ${ROOTDIR}etc/security/limits.conf exists" + LogText "Test: Checking if core dumps are disabled in ${ROOTDIR}etc/security/limits.conf and ${ROOTDIR}etc/security/limits.d/*" + FIND1=$(${GREPBINARY} -r -v "^#" ${ROOTDIR}etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="soft" && $3=="core" && $4=="0") { print "soft core disabled" } else if ($1=="*" && $2=="soft" && $3=="core" && $4!="0") { print "soft core enabled" } }') + FIND2=$(${GREPBINARY} -r -v "^#" ${ROOTDIR}etc/security/limits.conf ${LIMITS_DIRECTORY} | ${AWKBINARY} -F ":" '{print $2}' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="hard" && $3=="core" && $4=="0") { print "hard core disabled" } else if ($1=="*" && $2=="hard" && $3=="core" && $4!="0") { print "hard core enabled" } }') if [ "${FIND2}" = "hard core disabled" ]; then LogText "Result: core dumps (soft and hard) are both disabled" Display --indent 2 --text "- Checking core dumps configuration" --result "${STATUS_DISABLED}" --color GREEN @@ -461,7 +461,7 @@ AddHP 2 3 fi else - LogText "Result: file /etc/security/limits.conf does not exist, skipping test" + LogText "Result: file ${ROOTDIR}etc/security/limits.conf does not exist, skipping test" fi # TODO: Check ulimit settings in /etc/profile and /etc/profile.d @@ -490,13 +490,6 @@ fi # ################################################################################# -# - # Test : KRNL-5826 - # Description : Checking core dumps configuration (Solaris) - #Register --test-no KRNL-5826 --os Linux --weight L --network NO --category security --description "Checking core dumps configuration" - #if [ ${SKIPTEST} -eq 0 ]; then -# -################################################################################# # # Test : KRNL-5830 # Description : Check if system needs a reboot (Linux only) From c179a0e563b6f25ceacfbae55d15919d10e8ca82 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:36:56 +0200 Subject: [PATCH 17/23] Updated log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f26f84..ab6d1b78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ measures to further tighten any possible misuse. - Show 'lynis generate hostids' when they are missing - INSE-8116 - added rsync service - INSE-8342 - renamed to INSE-8304 +- KRNL-5820 - extended check to include limits.d directory - NAME-4408 - corrected Report function call - NETW-3032 - small rewrite of test and extended with addrwatch - PROC-3602 - allow different root directory From dbc6f9bc4cff8ea958e7bad923533a7f6db5a3bc Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:40:55 +0200 Subject: [PATCH 18/23] [SCHD-7702] removed hardening points --- include/tests_scheduling | 1 - 1 file changed, 1 deletion(-) diff --git a/include/tests_scheduling b/include/tests_scheduling index f0f54b5b..91a89c63 100644 --- a/include/tests_scheduling +++ b/include/tests_scheduling @@ -38,7 +38,6 @@ FIND=$(${PSBINARY} aux | ${EGREPBINARY} "( cron$|/cron(d)? )") if IsEmpty "${FIND}"; then LogText "Result: no cron daemon found" - AddHP 3 3 else LogText "Result: cron daemon running" CROND_RUNNING=1 From 5fdd00783e1cc508197924a3a73c15ac414dd26e Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 13:41:02 +0200 Subject: [PATCH 19/23] Updated log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab6d1b78..8161d49b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ measures to further tighten any possible misuse. - PROC-3602 - allow different root directory - PROC-3612 - show 'Not found' instead of 'OK' - PROC-3614 - show 'Not found' instead of 'OK' +- SCHD-7702 - removed hardening points - SSH-7402 - detect other SSH daemons like dropbear - SSH-7406 - strip OpenSSH patch version and remove characters (carriage return) - Whow changelog works again for newer versions From 591bc05f4d8b8b73941823ae804630e646ef1393 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 14:43:35 +0200 Subject: [PATCH 20/23] [SSH-7408] changed text in suggestion and report --- include/tests_ssh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/tests_ssh b/include/tests_ssh index dde395e3..8a55eabf 100644 --- a/include/tests_ssh +++ b/include/tests_ssh @@ -267,13 +267,13 @@ AddHP 3 3 elif [ "${RESULT}" = "MIDSCORED" ]; then LogText "Result: OpenSSH option ${OPTIONNAME} is configured reasonably" - ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (${FOUNDVALUE} --> ${EXPECTEDVALUE})" "-" + ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (set ${FOUNDVALUE} to ${EXPECTEDVALUE})" "-" ReportDetails --test "${TEST_NO}" --service "sshd" --field "${OPTIONNAME}" --value "${FOUNDVALUE}" --preferredvalue "${EXPECTEDVALUE}" --description "sshd option ${OPTIONNAME}" Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW AddHP 1 3 elif [ "${RESULT}" = "WEAK" ]; then LogText "Result: OpenSSH option ${OPTIONNAME} is in a weak configuration state and should be fixed" - ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (${FOUNDVALUE} --> ${EXPECTEDVALUE})" "-" + ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (set ${FOUNDVALUE} to ${EXPECTEDVALUE})" "-" ReportDetails --test "${TEST_NO}" --service "sshd" --field "${OPTIONNAME}" --value "${FOUNDVALUE}" --preferredvalue "${EXPECTEDVALUE}" --description "sshd option ${OPTIONNAME}" Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW AddHP 0 3 From ced78b52b0f757821b88d9a0c04bcf9a1f83b914 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 15:11:45 +0200 Subject: [PATCH 21/23] Small markup changes --- include/report | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/include/report b/include/report index 2df666e4..88d75ce0 100644 --- a/include/report +++ b/include/report @@ -22,8 +22,7 @@ # ################################################################################# # - - # Add data fields to report file + # Add additional data fields to the report file at the end of the scan Report "dhcp_client_running=${DHCP_CLIENT_RUNNING}" Report "arpwatch_running=${ARPWATCH_RUNNING}" @@ -37,10 +36,11 @@ Report "package_audit_tool=${PACKAGE_AUDIT_TOOL}" Report "package_audit_tool_found=${PACKAGE_AUDIT_TOOL_FOUND}" Report "vulnerable_packages_found=${VULNERABLE_PACKAGES_FOUND}" - - +# +################################################################################# +# # Hardening Index - + # # Goal: # Provide a visual way to show how much the system is hardened # @@ -95,8 +95,9 @@ HPGRAPH="[${HPCOLOR}${HPBLOCKS}${NORMAL}${HPEMPTY}]" LogText "Hardening index : [${HPINDEX}] [${HPBLOCKS}${HPEMPTY}]" LogText "Hardening strength: ${HIDESCRIPTION}" - - +# +################################################################################# +# # Only show overview if not running in quiet mode if [ ${QUIET} -eq 0 ]; then echo ""; echo "================================================================================" @@ -108,19 +109,14 @@ LogTextBreak - # - ################################################################################# - # # Show test results overview - # - ################################################################################# - # - if [ "${CONTROL_URL_PROTOCOL}" = "" ]; then CONTROL_URL_PROTOCOL="https"; fi - if [ "${CONTROL_URL_PREPEND}" = "" ]; then CONTROL_URL_PREPEND="cisofy.com/lynis/controls/"; fi - if [ "${CONTROL_URL_APPEND}" = "" ]; then CONTROL_URL_APPEND="/"; fi - if [ "${CUSTOM_URL_PROTOCOL}" = "" ]; then CUSTOM_URL_PROTOCOL="https"; fi - if [ "${CUSTOM_URL_PREPEND}" = "" ]; then CUSTOM_URL_PREPEND="your-domain.example.org/controls/"; fi - if [ "${CUSTOM_URL_APPEND}" = "" ]; then CUSTOM_URL_APPEND="/"; fi + + if [ -z "${CONTROL_URL_PROTOCOL}" ]; then CONTROL_URL_PROTOCOL="https"; fi + if [ -z "${CONTROL_URL_PREPEND}" ]; then CONTROL_URL_PREPEND="cisofy.com/lynis/controls/"; fi + if [ -z "${CONTROL_URL_APPEND}" ]; then CONTROL_URL_APPEND="/"; fi + if [ -z "${CUSTOM_URL_PROTOCOL}" ]; then CUSTOM_URL_PROTOCOL="https"; fi + if [ -z "${CUSTOM_URL_PREPEND}" ]; then CUSTOM_URL_PREPEND="your-domain.example.org/controls/"; fi + if [ -z "${CUSTOM_URL_APPEND}" ]; then CUSTOM_URL_APPEND="/"; fi # Show warnings from logfile SWARNINGS=$(${GREPBINARY} 'Warning: ' ${LOGFILE} | sed 's/ /!space!/g') @@ -249,7 +245,7 @@ if [ ! "${PROGRAM_LV}" = "0" -a ! "${REPORTFILE}" = "" -a ! "${REPORTFILE}" = "/dev/null" ]; then # Determine if the quality of the program can be increased by filtering out the exceptions FIND=$(${GREPBINARY} "^exception" ${REPORTFILE}) - if [ ! "${FIND}" = "" ]; then + if [ -n "${FIND}" ]; then echo "" echo " ${RED}${NOTE_EXCEPTIONS_FOUND}${NORMAL}" echo " ${WHITE}${NOTE_EXCEPTIONS_FOUND_DETAILED}!${NORMAL}" From c074c81897d1b5c4ef60447971a8d25505681bd8 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 15:12:25 +0200 Subject: [PATCH 22/23] Initial work on GetReportData function --- include/functions | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/functions b/include/functions index 794abcc4..c8f689e7 100644 --- a/include/functions +++ b/include/functions @@ -52,6 +52,7 @@ # FileIsEmpty Check if a file is empty # FileIsReadable Check if a file is readable or directory accessible # GetHostID Retrieve an unique ID for this host +# GetReportData Request data from report # HasData Checks for data in variable # InsertSection Insert a section block # InsertPluginSection Insert a section block for plugins @@ -1176,6 +1177,47 @@ fi } + + ################################################################################ + # Name : GetReportData() + # Description : Request data from report + # Returns : Data (when matches were found) + # Exit code: True (0) or False (1) when search was cancelled + ################################################################################ + + GetReportData() { + KEY="" + VALID_CHARS="[:alnum:]/:;\-,\._\[\]\n " + if [ $# -eq 0 ]; then ExitFatal "No parameters provided to GetReportData() function"; fi + + while [ $# -ge 1 ]; do + case $1 in + --key) + shift + KEY="$1" + ;; + --valid-chars) + shift + VALID_CHARS="$1" + ;; + *) + ExitFatal "Invalid option provided to GetReportData() function" + ;; + esac + # Go to next parameter + shift + done + + if [ "${REPORTFILE}" = "/dev/null" ]; then + return 1 + else + ${AWKBINARY} -v pattern="^${KEY}" -F= '$1 ~ pattern {print $2}' ${REPORTFILE} | ${TRBINARY} -cd "${VALID_CHARS}" | ${TRBINARY} '[:blank:]' '__space__' + + fi + return 0 + } + + ################################################################################ # Name : HasData() # Description : Check for a filled variable From 5cc5ecf534371b7eea6f7666b7b6e798d5d10de2 Mon Sep 17 00:00:00 2001 From: Michael Boelen Date: Sun, 14 Jul 2019 15:13:02 +0200 Subject: [PATCH 23/23] Updated log --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8161d49b..95664374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ measures to further tighten any possible misuse. - Security: test if setuid bit is set on Lynis binary - New function: DisplayWarning - show a warning on the screen - New function: Equals - compare two strings +- New function: GetReportData - retrieve earlier stored data - New function: Readonly - mark variable read-only (security) - New function: SafeFile - test file type and call permission check - New function: SafeInput - check for safe input (security) @@ -54,6 +55,7 @@ measures to further tighten any possible misuse. - SCHD-7702 - removed hardening points - SSH-7402 - detect other SSH daemons like dropbear - SSH-7406 - strip OpenSSH patch version and remove characters (carriage return) +- SSH-7408 - changed text in suggestion and report - Whow changelog works again for newer versions - systemd service file adjusted - bash completion script extended