mirror of https://github.com/CISOfy/lynis.git
930 lines
60 KiB
Bash
930 lines
60 KiB
Bash
#!/bin/sh
|
|
|
|
#################################################################################
|
|
#
|
|
# Lynis
|
|
# ------------------
|
|
#
|
|
# Copyright 2007-2013, Michael Boelen
|
|
# Copyright 2007-2021, CISOfy
|
|
#
|
|
# Website : https://cisofy.com
|
|
# Blog : http://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.
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Kernel
|
|
#
|
|
#################################################################################
|
|
#
|
|
InsertSection "${SECTION_KERNEL}"
|
|
#
|
|
#################################################################################
|
|
#
|
|
CPU_PAE=0
|
|
CPU_NX=0
|
|
LINUXCONFIGFILE=""
|
|
LINUXCONFIGFILE_ZIPPED=0
|
|
LIMITS_DIRECTORY="${ROOTDIR}etc/security/limits.d"
|
|
APT_ARCHIVE_DIRECTORY="${ROOTDIR}var/cache/apt/archives"
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5622
|
|
# Description : Check default run level on Linux machines
|
|
Register --test-no KRNL-5622 --os Linux --weight L --network NO --category security --description "Determine Linux default run level"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
# Checking if we can find the systemd default target
|
|
LogText "Test: Checking for systemd default.target"
|
|
if [ $( [ ! -z ${SYSTEMCTLBINARY} ] && ${SYSTEMCTLBINARY} get-default) ]; then
|
|
FIND=$(${SYSTEMCTLBINARY} get-default)
|
|
FIND2=$(${ECHOCMD} ${FIND} | ${EGREPBINARY} "runlevel5|graphical")
|
|
if HasData "${FIND2}"; then
|
|
LogText "Result: Found match on runlevel5/graphical"
|
|
Display --indent 2 --text "- Checking default runlevel" --result "runlevel 5" --color GREEN
|
|
Report "linux_default_runlevel=5"
|
|
else
|
|
LogText "Result: No match found on runlevel, defaulting to runlevel 3"
|
|
Display --indent 2 --text "- Checking default runlevel" --result "runlevel 3" --color GREEN
|
|
Report "linux_default_runlevel=3"
|
|
fi
|
|
else
|
|
LogText "Result: no systemd found, so trying inittab"
|
|
LogText "Test: Checking ${ROOTDIR}etc/inittab"
|
|
if [ -f ${ROOTDIR}etc/inittab ]; then
|
|
LogText "Result: file ${ROOTDIR}etc/inittab found"
|
|
LogText "Test: Checking default Linux run level"
|
|
FIND=$(${AWKBINARY} -F: '/^id/ { print $2; }' ${ROOTDIR}etc/inittab | head -n 1)
|
|
if IsEmpty "${FIND}"; then
|
|
Display --indent 2 --text "- Checking default runlevel" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
LogText "Result: Can't determine default run level from ${ROOTDIR}etc/inittab"
|
|
else
|
|
Display --indent 2 --text "- Checking default run level" --result "${FIND}" --color GREEN
|
|
LogText "Found default run level '${FIND}'"
|
|
Report "linux_default_runlevel=${FIND}"
|
|
fi
|
|
else
|
|
LogText "Result: file ${ROOTDIR}etc/inittab not found"
|
|
if [ "${LINUX_VERSION}" = "Debian" ] || [ "${LINUX_VERSION}" = "Ubuntu" ] || [ "${LINUX_VERSION_LIKE}" = "Debian" ] || [ "${LINUX_VERSION_LIKE}" = "Ubuntu" ]; then
|
|
LogText "Test: Checking run level with who -r, for Debian based systems"
|
|
FIND=$(who -r | ${AWKBINARY} '{ if ($1=="run-level") { print $2 } }')
|
|
if HasData "${FIND}"; then
|
|
LogText "Result: Found default run level '${FIND}'"
|
|
Report "linux_default_runlevel=${FIND}"
|
|
Display --indent 2 --text "- Checking default run level" --result "RUNLEVEL ${FIND}" --color GREEN
|
|
else
|
|
LogText "Result: Can't determine default run level from who -r"
|
|
Display --indent 2 --text "- Checking default run level" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5677
|
|
# Description : Check CPU options and support (PAE, No eXecute, eXecute Disable)
|
|
# More info : pae and nx bit are both visible on AMD and Intel CPU's if supported
|
|
|
|
Register --test-no KRNL-5677 --platform "x86_64 amd64" --os "Linux NetBSD" --weight L --network NO --category security --description "Check CPU options and support"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
Display --indent 2 --text "- Checking CPU support (NX/PAE)"
|
|
LogText "Test: Checking /proc/cpuinfo"
|
|
if [ -f /proc/cpuinfo ]; then
|
|
LogText "Result: found /proc/cpuinfo"
|
|
LogText "Test: Checking CPU options (XD/NX/PAE)"
|
|
FIND_PAE_NX=$(${GREPBINARY} " pae " /proc/cpuinfo | ${GREPBINARY} " nx ")
|
|
FIND_PAE=$(${GREPBINARY} " pae " /proc/cpuinfo)
|
|
FIND_NX=$(${GREPBINARY} " nx " /proc/cpuinfo)
|
|
FOUND=0
|
|
if HasData "${FIND_PAE_NX}"; then
|
|
LogText "PAE: Yes"
|
|
LogText "NX: Yes"
|
|
CPU_PAE=1
|
|
CPU_NX=1
|
|
LogText "Result: PAE or No eXecute option(s) both found"
|
|
Report "cpu_pae=1"
|
|
Report "cpu_nx=1"
|
|
FOUND=1
|
|
else
|
|
if HasData "${FIND_PAE}" && IsEmpty "${FIND_NX}"; then
|
|
Report "cpu_pae=1"
|
|
LogText "Result: found PAE"
|
|
CPU_PAE=1
|
|
FOUND=1
|
|
else
|
|
if HasData "${FIND_NX}" && IsEmpty "${FIND_PAE}"; then
|
|
Report "cpu_nx=1"
|
|
LogText "Result: found No eXecute"
|
|
CPU_NX=1
|
|
FOUND=1
|
|
else
|
|
LogText "Result: found no CPU options enabled (PAE or NX bit)"
|
|
fi
|
|
fi
|
|
fi
|
|
if [ ${FOUND} -eq 1 ]; then
|
|
Display --indent 4 --text "CPU support: PAE and/or NoeXecute supported" --result "${STATUS_FOUND}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "CPU support: No PAE or NoeXecute supported" --result "${STATUS_NONE}" --color YELLOW
|
|
ReportSuggestion "${TEST_NO}" "Use a PAE enabled kernel when possible to gain native No eXecute/eXecute Disable support"
|
|
fi
|
|
else
|
|
Display --indent 4 --text "CPU support: no /proc/cpuinfo" --result "${STATUS_SKIPPED}" --color YELLOW
|
|
LogText "Result: /proc/cpuinfo not found"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5680
|
|
# Description : Check if installed kernel has PAE support
|
|
# Dependency : KRNL-5677
|
|
# More info : RedHat/CentOS/Fedora uses the package name 'kernel-PAE'
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5695
|
|
# Description : Determining Linux kernel version and release number
|
|
Register --test-no KRNL-5695 --os Linux --weight L --network NO --category security --description "Determine Linux kernel version and release number"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
# Kernel number (and suffix)
|
|
LINUX_KERNEL_RELEASE=$(uname -r)
|
|
Report "linux_kernel_release=${LINUX_KERNEL_RELEASE}"
|
|
LogText "Result: found kernel release ${LINUX_KERNEL_RELEASE}"
|
|
# Type and build date
|
|
LINUX_KERNEL_VERSION=$(uname -v)
|
|
Report "linux_kernel_version=${LINUX_KERNEL_VERSION}"
|
|
LogText "Result: found kernel version ${LINUX_KERNEL_VERSION}"
|
|
Display --indent 2 --text "- Checking kernel version and release" --result "${STATUS_DONE}" --color GREEN
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5723
|
|
# Description : Check if Linux is build as a monolithic kernel or not
|
|
Register --test-no KRNL-5723 --os Linux --weight L --network NO --category security --description "Determining if Linux kernel is monolithic"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
if [ -n "${LSMODBINARY}" -a -f /proc/modules ]; then
|
|
LogText "Test: checking if kernel is monolithic or modular"
|
|
# Checking if any modules are loaded
|
|
FIND=$(${LSMODBINARY} | ${GREPBINARY} -v "^Module" | wc -l | ${TRBINARY} -s ' ' | ${TRBINARY} -d ' ')
|
|
Display --indent 2 --text "- Checking kernel type" --result "${STATUS_DONE}" --color GREEN
|
|
MONOLITHIC_KERNEL_TESTED=1
|
|
if [ "${FIND}" = "0" ]; then
|
|
LogText "Result: Found monolithic kernel"
|
|
Report "linux_kernel_type=monolithic"
|
|
MONOLITHIC_KERNEL=1
|
|
else
|
|
LogText "Result: Found modular kernel"
|
|
Report "linux_kernel_type=modular"
|
|
MONOLITHIC_KERNEL=0
|
|
fi
|
|
else
|
|
LogText "Test skipped, lsmod binary not found or /proc/modules can not be opened"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5726
|
|
# Description : Checking Linux loaded kernel modules
|
|
Register --test-no KRNL-5726 --os Linux --weight L --network NO --category security --description "Checking Linux loaded kernel modules"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
if [ -n "${LSMODBINARY}" -a -f /proc/modules ]; then
|
|
FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ if ($1!="Module") print $1 }' | sort)
|
|
Display --indent 2 --text "- Checking loaded kernel modules" --result "${STATUS_DONE}" --color GREEN
|
|
if HasData "${FIND}"; then
|
|
LogText "Loaded modules according lsmod:"
|
|
COUNT=0
|
|
for ITEM in ${FIND}; do
|
|
LogText "Loaded module: ${ITEM}"
|
|
Report "loaded_kernel_module[]=${ITEM}"
|
|
COUNT=$((COUNT + 1))
|
|
done
|
|
Display --indent 6 --text "Found ${COUNT} active modules"
|
|
else
|
|
LogText "Result: no loaded modules found"
|
|
LogText "Notice: No loaded kernel modules could indicate a broken/malformed lsmod, or a (custom) monolithic kernel"
|
|
fi
|
|
else
|
|
LogText "Test skipped, lsmod binary not found or /proc/modules can not be opened"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5728
|
|
# 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="${ROOTDIR}boot/config-$(uname -r)"
|
|
CHECKFILE_ZIPPED="${ROOTDIR}proc/config.gz"
|
|
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 ${CHECKFILE_ZIPPED} ]; then
|
|
LINUXCONFIGFILE="${CHECKFILE_ZIPPED}"
|
|
LINUXCONFIGFILE_ZIPPED=1
|
|
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 ${ROOTDIR}boot"
|
|
Display --indent 2 --text "- Checking Linux kernel configuration file" --result "${STATUS_NOT_FOUND}" --color WHITE
|
|
fi
|
|
if HasData "${LINUXCONFIGFILE}"; then
|
|
Report "linux_config_file=${LINUXCONFIGFILE}"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5730
|
|
# Description : Checking default I/O kernel scheduler
|
|
# Notes : This test could be extended with testing some of the specific devices like disks
|
|
# cat /sys/block/sda/queue/scheduler
|
|
PREQS_MET="NO"
|
|
if HasData "${LINUXCONFIGFILE}"; then
|
|
if [ -f ${LINUXCONFIGFILE} ]; then PREQS_MET="YES"; fi
|
|
fi
|
|
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 [ -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 [ -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"
|
|
Display --indent 2 --text "- Checking default I/O kernel scheduler" --result "${STATUS_NOT_FOUND}" --color WHITE
|
|
fi
|
|
else
|
|
ReportException "${TEST_NO}" "No valid ${GREPBINARY} tool found to search kernel settings"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5745
|
|
# Description : Checking FreeBSD loaded kernel modules
|
|
Register --test-no KRNL-5745 --os FreeBSD --weight L --network NO --category security --description "Checking FreeBSD loaded kernel modules"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
Display --indent 2 --text "- Checking active kernel modules"
|
|
LogText "Test: Active kernel modules (KLDs)"
|
|
LogText "Description: View all active kernel modules (including kernel)"
|
|
LogText "Test: Checking modules"
|
|
if [ -f /sbin/kldstat ]; then
|
|
FIND=$(kldstat | ${GREPBINARY} -v 'Name' | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f6)
|
|
if [ $? -eq 0 ]; then
|
|
LogText "Loaded modules according kldstat:"
|
|
COUNT=0
|
|
for ITEM in ${FIND}; do
|
|
LogText "Loaded module: ${ITEM}"
|
|
Report "loaded_kernel_module[]=${ITEM}"
|
|
COUNT=$((COUNT + 1))
|
|
done
|
|
Display --indent 4 --text "Found ${COUNT} kernel modules" --result "${STATUS_DONE}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "Test failed" --result "${STATUS_WARNING}" --color RED
|
|
LogText "Result: Problem with executing kldstat"
|
|
fi
|
|
else
|
|
LogText "Result: no results, can't find /sbin/kldstat"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5831
|
|
# Description : Checking DragonFly loaded kernel modules
|
|
Register --test-no KRNL-5831 --os DragonFly --weight L --network NO --category security --description "Checking DragonFly loaded kernel modules"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
Display --indent 2 --text "- Checking active kernel modules"
|
|
LogText "Test: Active kernel modules (KLDs)"
|
|
LogText "Description: View all active kernel modules (including kernel)"
|
|
LogText "Test: Checking modules"
|
|
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
|
|
for ITEM in ${FIND}; do
|
|
LogText "Loaded module: ${ITEM}"
|
|
Report "loaded_kernel_module[]=${ITEM}"
|
|
COUNT=$((COUNT + 1))
|
|
done
|
|
Display --indent 4 --text "Found ${COUNT} kernel modules" --result "${STATUS_DONE}" --color GREEN
|
|
else
|
|
Display --indent 4 --text "Test failed" --result "${STATUS_WARNING}" --color RED
|
|
LogText "Result: Problem with executing kldstat"
|
|
fi
|
|
else
|
|
echo "[ ${WHITE}SKIPPED${NORMAL} ]"
|
|
LogText "Result: no results, can NOT find /sbin/kldstat"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5770
|
|
# Description : Checking Solaris load modules
|
|
Register --test-no KRNL-5770 --os Solaris --weight L --network NO --category security --description "Checking active kernel modules"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
LogText "Test: searching loaded kernel modules"
|
|
FIND=$(/usr/sbin/modinfo -c -w | ${GREPBINARY} -v "UNLOADED" | ${GREPBINARY} LOADED | ${AWKBINARY} '{ print $3 }' | sort)
|
|
if HasData "${FIND}"; then
|
|
for ITEM in ${FIND}; do
|
|
LogText "Found module: ${ITEM}"
|
|
Report "loaded_kernel_module[]=${ITEM}"
|
|
done
|
|
Display --indent 2 --text "- Checking Solaris active kernel modules" --result "${STATUS_DONE}" --color GREEN
|
|
else
|
|
LogText "Result: no output"
|
|
Display --indent 2 --text "- Checking Solaris active kernel modules" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5788
|
|
# Description : Checking availability new kernel
|
|
if [ "${LINUX_VERSION}" = "Debian" ] || [ "${LINUX_VERSION}" = "Ubuntu" ] || [ "${LINUX_VERSION_LIKE}" = "Debian" ] || [ "${LINUX_VERSION_LIKE}" = "Ubuntu" ]; then
|
|
PREQS_MET="YES"
|
|
else
|
|
PREQS_MET="NO"
|
|
fi
|
|
Register --test-no KRNL-5788 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking availability new Linux kernel"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FINDKERNEL=""
|
|
HAS_VMLINUZ=0
|
|
LogText "Test: Searching apt-cache, to determine if a newer kernel is available"
|
|
if [ -x ${ROOTDIR}usr/bin/apt-cache ]; then
|
|
LogText "Result: found ${ROOTDIR}usr/bin/apt-cache"
|
|
LogText "Test: checking presence of ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz"
|
|
if [ -f ${ROOTDIR}vmlinuz -o -f ${ROOTDIR}boot/vmlinuz ]; then
|
|
HAS_VMLINUZ=1
|
|
if [ -f ${ROOTDIR}vmlinuz ]; then
|
|
FINDVMLINUZ="${ROOTDIR}vmlinuz"
|
|
else
|
|
FINDVMLINUZ="${ROOTDIR}boot/vmlinuz"
|
|
fi
|
|
LogText "Result: found ${FINDVMLINUZ}"
|
|
LogText "Test: checking readlink location of ${FINDVMLINUZ}"
|
|
FINDKERNFILE=$(readlink -f ${FINDVMLINUZ})
|
|
LogText "Output: readlink reported file ${FINDKERNFILE}"
|
|
LogText "Test: checking relevant package using output from dpkg -S"
|
|
FINDKERNEL=$(dpkg -S ${FINDKERNFILE} 2> /dev/null | ${AWKBINARY} -F : '{print $1}')
|
|
LogText "Output: dpkg -S reported package ${FINDKERNEL}"
|
|
elif [ -e ${ROOTDIR}dev/grsec ]; then
|
|
FINDKERNEL="linux-image-$(uname -r)"
|
|
LogText "Result: ${ROOTDIR}vmlinuz missing due to grsecurity; assuming ${FINDKERNEL}"
|
|
elif [ -e ${ROOTDIR}etc/rpi-issue ]; then
|
|
FINDKERNEL="raspberrypi-kernel"
|
|
LogText "Result: ${ROOTDIR}vmlinuz missing due to Raspbian"
|
|
elif $(${GREPBINARY} -E -q 'do_symlinks.*=.*No' ${ROOTDIR}etc/kernel-img.conf); then
|
|
FINDKERNEL="linux-image-$(uname -r)"
|
|
LogText "Result: ${ROOTDIR}vmlinuz missing due to /etc/kernel-img.conf item do_symlinks = No"
|
|
else
|
|
LogText "This system is missing ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz. Unable to check whether kernel is up-to-date."
|
|
ReportSuggestion "${TEST_NO}" "Determine why ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz is missing on this Debian/Ubuntu system." "/vmlinuz or /boot/vmlinuz"
|
|
fi
|
|
|
|
if IsEmpty "${FINDKERNEL}"; then
|
|
LogText "Result: could not check kernel update status as kernel is unknown"
|
|
else
|
|
LogText "Result: found kernel '${FINDKERNEL}' which will be used for further testing"
|
|
LogText "Test: Using apt-cache policy to determine if there is an update available"
|
|
FINDINSTALLED=$(apt-cache policy ${FINDKERNEL} | ${GREPBINARY} -E 'Installed' | ${CUTBINARY} -d ':' -f2 | ${TRBINARY} -d ' ')
|
|
FINDCANDIDATE=$(apt-cache policy ${FINDKERNEL} | ${GREPBINARY} -E 'Candidate' | ${CUTBINARY} -d ':' -f2 | ${TRBINARY} -d ' ')
|
|
LogText "Kernel installed: ${FINDINSTALLED}"
|
|
LogText "Kernel candidate: ${FINDCANDIDATE}"
|
|
if IsEmpty "${FINDINSTALLED}"; then
|
|
Display --indent 2 --text "- Checking for available kernel update" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
LogText "Result: Exception occurred, no output from apt-cache policy"
|
|
if [ ${HAS_VMLINUZ} -eq 1 ]; then
|
|
ReportException "${TEST_NO}:01" "Found vmlinuz (${FINDVMLINUZ}) but could not determine the installed kernel using apt-cache policy"
|
|
ReportSuggestion "${TEST_NO}" "Check the output of apt-cache policy to determine why its output is empty"
|
|
fi
|
|
LogText "Result: apt-cache policy did not return an installed kernel version"
|
|
else
|
|
if [ "${FINDINSTALLED}" = "${FINDCANDIDATE}" ]; then
|
|
if [ -e /dev/grsec ]; then
|
|
Display --indent 2 --text "- Checking for available kernel update" --result GRSEC --color GREEN
|
|
LogText "Result: Grsecurity is installed; unable to determine if there's a newer kernel available"
|
|
ReportManual "Manually check to confirm you're using a recent kernel and grsecurity patch"
|
|
else
|
|
Display --indent 2 --text "- Checking for available kernel update" --result "${STATUS_OK}" --color GREEN
|
|
LogText "Result: no kernel update available"
|
|
fi
|
|
else
|
|
Display --indent 2 --text "- Checking for available kernel update" --result "UPDATE AVAILABLE" --color YELLOW
|
|
LogText "Result: kernel update available according 'apt-cache policy'."
|
|
ReportSuggestion "${TEST_NO}" "Determine priority for available kernel update"
|
|
fi
|
|
fi
|
|
fi
|
|
else
|
|
LogText "Result: could NOT find ${ROOTDIR}usr/bin/apt-cache, skipped other tests."
|
|
fi
|
|
unset FINDCANDIDATE FINDINSTALLED FINDKERNEL HAS_VMLINUZ
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5820
|
|
# 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
|
|
Display --indent 2 --text "- Checking core dumps configuration"
|
|
LogText "Test: Checking presence of systemd"
|
|
# systemd option
|
|
if [ $HAS_SYSTEMD -eq 1 ]; then
|
|
LogText "Result: systemd is present on this system"
|
|
LogText "Test: Checking if core dumps are disabled in ${ROOTDIR}etc/systemd/coredump.conf and ${ROOTDIR}etc/systemd/coredump.conf.d/*.conf"
|
|
# check likely main config file for systemd: ${ROOTDIR}etc/systemd/coredump.conf for ProcessSizeMax=0 and Storage=none
|
|
SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED=$(${GREPBINARY} -v "^ *#" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i "^ProcessSizeMax=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g' | ${GREPBINARY} "^0 *$" | ${WCBINARY} -l)
|
|
SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED=$(${GREPBINARY} -v "^ *#" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i "^ProcessSizeMax=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g' | ${GREPBINARY} -v "^0 *$" | ${WCBINARY} -l)
|
|
SYSD_CORED_BASE_STORAGE_FOUND=$(${GREPBINARY} -v "^ *#" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i "^Storage=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g')
|
|
SYSD_CORED_BASE_STORAGE_NR_ENABLED=$(${ECHOCMD} "${SYSD_CORED_BASE_STORAGE_FOUND}" | ${SEDBINARY} 's/none//g' | ${WCBINARY} | ${AWKBINARY} '{print $2}')
|
|
SYSD_CORED_BASE_STORAGE_NR_DISABLED=$(${ECHOCMD} "${SYSD_CORED_BASE_STORAGE_FOUND}" | ${GREPBINARY} -o "none" | ${WCBINARY} | ${AWKBINARY} '{print $2}')
|
|
# check conf files in possibly existing coredump.conf.d folders
|
|
# using find instead of grep -r to stay POSIX compliant. On AIX and HPUX grep -r is not available.
|
|
# while there could be multiple files overwriting each other, we are checking the number of occurrences
|
|
SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname "*.conf" -exec ${SEDBINARY} 's/^ *//g' {} \; 2> /dev/null | ${GREPBINARY} -i "^ProcessSizeMax=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g' | ${GREPBINARY} "^0 *$" | ${WCBINARY} -l)
|
|
SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname "*.conf" -exec ${SEDBINARY} 's/^ *//g' {} \; 2> /dev/null | ${GREPBINARY} -i "^ProcessSizeMax=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g' | ${GREPBINARY} -v "^0 *$" | ${WCBINARY} -l)
|
|
SYSD_CORED_SUB_STORAGE_FOUND=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname "*.conf" -exec ${SEDBINARY} 's/^ *//g' {} \; 2> /dev/null | ${GREPBINARY} -i "^Storage=" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g')
|
|
SYSD_CORED_SUB_STORAGE_NR_ENABLED=$(${ECHOCMD} "${SYSD_CORED_SUB_STORAGE_FOUND}" | ${SEDBINARY} 's/none//g' | ${WCBINARY} | ${AWKBINARY} '{print $2}')
|
|
SYSD_CORED_SUB_STORAGE_NR_DISABLED=$(${ECHOCMD} "${SYSD_CORED_SUB_STORAGE_FOUND}" | ${GREPBINARY} -o "none" | ${WCBINARY} | ${AWKBINARY} '{print $2}')
|
|
if ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \
|
|
( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \
|
|
( [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \
|
|
( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ); then
|
|
LogText "Result: core dumps are disabled by 'ProcessSizeMax=0' and 'Storage=none' in systemd configuration files"
|
|
AddHP 1 1
|
|
TMP_COLOR="GREEN"
|
|
if [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -gt 1 ]; then
|
|
LogText "Result: 'ProcessSizeMax=0' and 'Storage=none' are set multiple times in systemd configuration files. Check config!"
|
|
ReportSuggestion "${TEST_NO}" "Check systemd configuration for duplicate entries of core dump settings"
|
|
TMP_COLOR="YELLOW"
|
|
fi
|
|
Display --indent 4 --text "- configuration in systemd conf files" --result "${STATUS_DISABLED}" --color "${TMP_COLOR}"
|
|
elif [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && ( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] || [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ); then
|
|
LogText "Result: 'ProcessSizeMax=0' and 'Storage=none' are set in ${ROOTDIR}etc/systemd/coredump.conf but overwritten in subdir config files"
|
|
ReportSuggestion "${TEST_NO}" "Check systemd configuration for overwriting core dump settings"
|
|
Display --indent 4 --text "- configuration in systemd conf files" --result "${STATUS_ENABLED}" --color YELLOW
|
|
AddHP 0 1
|
|
elif ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_ENABLED} -ge 1 ] ) || \
|
|
( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ) || \
|
|
( [ ${SYSD_CORED_BASE_STORAGE_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] ) || \
|
|
( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ); then
|
|
LogText "Result: core dumps are explicitly enabled in systemd configuration files"
|
|
ReportSuggestion "${TEST_NO}" "If not required, consider explicit disabling of core dump in ${ROOTDIR}etc/systemd/coredump.conf ('ProcessSizeMax=0', 'Storage=none')"
|
|
Display --indent 4 --text "- configuration in systemd conf files" --result "${STATUS_ENABLED}" --color RED
|
|
AddHP 0 1
|
|
else
|
|
LogText "Result: core dumps are not disabled in systemd configuration. Didn't find settings 'ProcessSizeMax=0' and 'Storage=none'"
|
|
Display --indent 4 --text "- configuration in systemd conf files" --result "${STATUS_DEFAULT}" --color WHITE
|
|
AddHP 0 1
|
|
fi
|
|
fi
|
|
# Profile option
|
|
LogText "Test: Checking presence ${ROOTDIR}etc/profile"
|
|
if [ -f "${ROOTDIR}etc/profile" ]; then
|
|
LogText "Test: Checking if 'ulimit -c 0' exists in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh"
|
|
# use tail -1 in the following commands to get the last entry, which is the one that counts (in case of profile.d/ probably counts)
|
|
ULIMIT_C_VALUE="$(${GREPBINARY} "ulimit -H\?c " ${ROOTDIR}etc/profile 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -v "^#" | ${TAILBINARY} -1 | ${CUTBINARY} -d' ' -f3 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g')"
|
|
ULIMIT_C_VALUE_SUB="$(${FINDBINARY} -L ${ROOTDIR}etc/profile.d -name "*.sh" -type f -exec ${CAT_BINARY} {} \; 2> /dev/null | ${GREPBINARY} "ulimit -H\?c " | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -v "^#" | ${TAILBINARY} -1 | ${CUTBINARY} -d' ' -f3 | ${SEDBINARY} 's/ .*$//g ; s/\([A-Z][a-z]*\)*$//g')"
|
|
if ( [ -n "${ULIMIT_C_VALUE_SUB}" ] && [ "${ULIMIT_C_VALUE_SUB}" = "0" ] ) || ( [ -n "${ULIMIT_C_VALUE}" ] && [ -z "${ULIMIT_C_VALUE_SUB}" ] && [ "${ULIMIT_C_VALUE}" = "0" ] ); then
|
|
LogText "Result: core dumps are disabled by 'ulimit -c 0' in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh"
|
|
Display --indent 4 --text "- configuration in etc/profile" --result "${STATUS_DISABLED}" --color GREEN
|
|
AddHP 1 1
|
|
elif [ -z "${ULIMIT_C_VALUE_SUB}" ] && [ -z "${ULIMIT_C_VALUE}" ]; then
|
|
LogText "Result: core dumps are not disabled in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh config files. Didn't find setting 'ulimit -c 0'"
|
|
Display --indent 4 --text "- configuration in ${ROOTDIR}etc/profile" --result "${STATUS_DEFAULT}" --color WHITE
|
|
AddHP 0 1
|
|
elif ( [ -n "${ULIMIT_C_VALUE_SUB}" ] && ( [ "${ULIMIT_C_VALUE_SUB}" = "unlimited" ] || [ "${ULIMIT_C_VALUE_SUB}" != "0" ] ) ) || ( [ -n "${ULIMIT_C_VALUE}" ] && [ -z "${ULIMIT_C_VALUE_SUB}" ] && ( [ "${ULIMIT_C_VALUE}" = "unlimited" ] || [ "${ULIMIT_C_VALUE}" != "0" ] ) ); then
|
|
LogText "Result: core dumps are enabled in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh config files. A value higher than 0 is configured for 'ulimit -c'"
|
|
Display --indent 4 --text "- configuration in ${ROOTDIR}etc/profile" --result "${STATUS_ENABLED}" --color RED
|
|
AddHP 0 1
|
|
else
|
|
LogText "Result: ERROR - something went wrong. Unexpected result during check of ${ROOTDIR}etc/profile and ${ROOTDIR}etc/profile.d/*.sh config files. Please report on Github!"
|
|
Display --indent 4 --text "- configuration in ${ROOTDIR}etc/profile" --result "${STATUS_ERROR}" --color YELLOW
|
|
fi
|
|
fi
|
|
|
|
# Limits options
|
|
for DIR in "/" "/usr/"; do
|
|
LogText "Test: Checking presence ${DIR}etc/security/limits.conf"
|
|
if [ -f "${DIR}etc/security/limits.conf" ]; then
|
|
LogText "Result: file ${DIR}etc/security/limits.conf exists"
|
|
LogText "Test: Checking if core dumps are disabled in ${DIR}etc/security/limits.conf and ${LIMITS_DIRECTORY}/*"
|
|
# using find instead of grep -r to stay POSIX compliant. On AIX and HPUX grep -r is not available.
|
|
FIND1=$(${FINDBINARY} -L "${DIR}etc/security/limits.conf" "${LIMITS_DIRECTORY}" -type f -exec ${CAT_BINARY} {} \; 2> /dev/null | ${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" } }' | ${TAILBINARY} -1)
|
|
FIND2=$(${FINDBINARY} -L "${DIR}etc/security/limits.conf" "${LIMITS_DIRECTORY}" -type f -exec ${CAT_BINARY} {} \; 2> /dev/null | ${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" } }' | ${TAILBINARY} -1)
|
|
FIND3=$(${FINDBINARY} -L "${DIR}etc/security/limits.conf" "${LIMITS_DIRECTORY}" -type f -exec ${CAT_BINARY} {} \; 2> /dev/null | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ if ($1=="*" && $2=="-" && $3=="core" && $4=="0") { print "core dumps disabled" } else if ($1=="*" && $2=="-" && $3=="core" && $4!="0") { print "core dumps enabled" } }' | ${TAILBINARY} -1)
|
|
|
|
# When "* - core [value]" is used, then this sets both soft and core. In that case we set the values, as they the type 'hard' and 'soft' will not be present in the configuration file.
|
|
if [ "${FIND3}" = "core dumps disabled" ]; then
|
|
FIND1="soft core disabled"
|
|
FIND2="hard core disabled"
|
|
elif [ "${FIND3}" = "core dumps enabled" ]; then
|
|
FIND1="soft core enabled"
|
|
FIND2="hard core enabled"
|
|
fi
|
|
|
|
IS_SOFTCORE_DISABLED="$(if [ "${FIND1}" = "soft core disabled" ]; then ${ECHOCMD} DISABLED; elif [ "${FIND1}" = "soft core enabled" ]; then ${ECHOCMD} ENABLED; else ${ECHOCMD} ${STATUS_DEFAULT}; fi)"
|
|
IS_HARDCORE_DISABLED="$(if [ "${FIND2}" = "hard core disabled" ]; then ${ECHOCMD} DISABLED; elif [ "${FIND2}" = "hard core enabled" ]; then ${ECHOCMD} ENABLED; else ${ECHOCMD} ${STATUS_DEFAULT}; fi)"
|
|
|
|
if [ "${FIND2}" = "hard core disabled" ]; then
|
|
LogText "Result: core dumps are hard disabled"
|
|
Display --indent 4 --text "- 'hard' configuration in ${DIR}etc/security/limits.conf" --result "${IS_HARDCORE_DISABLED}" --color "GREEN"
|
|
if [ "${FIND1}" = "soft core disabled" ]; then
|
|
Display --indent 4 --text "- 'soft' configuration in ${DIR}etc/security/limits.conf" --result "${IS_SOFTCORE_DISABLED}" --color "GREEN"
|
|
else
|
|
Display --indent 4 --text "- 'soft' config in ${DIR}etc/security/limits.conf (implicit)" --result "${STATUS_DISABLED}" --color "GREEN"
|
|
fi
|
|
AddHP 3 3
|
|
elif [ "${FIND1}" = "soft core enabled" ] && [ "${FIND2}" = "hard core enabled" ]; then
|
|
LogText "Result: core dumps (soft and hard) are enabled"
|
|
Display --indent 4 --text "- 'hard' configuration in ${DIR}etc/security/limits.conf" --result "${STATUS_ENABLED}" --color "RED"
|
|
Display --indent 4 --text "- 'soft' configuration in ${DIR}etc/security/limits.conf" --result "${STATUS_ENABLED}" --color "RED"
|
|
ReportSuggestion "${TEST_NO}" "If not required, consider explicit disabling of core dump in /etc/security/limits.conf file"
|
|
AddHP 0 3
|
|
elif [ "${FIND1}" = "soft core disabled" ]; then
|
|
LogText "Result: core dumps are disabled for 'soft' ('hard'=${IS_HARDCORE_DISABLED})"
|
|
Display --indent 4 --text "- 'hard' configuration in ${DIR}etc/security/limits.conf" --result "${IS_HARDCORE_DISABLED}" --color "$(if [ "${IS_HARDCORE_DISABLED}" = "ENABLED" ]; then ${ECHOCMD} RED; elif [ "${IS_HARDCORE_DISABLED}" = "DISABLED" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)"
|
|
Display --indent 4 --text "- 'soft' configuration in ${DIR}etc/security/limits.conf" --result "${IS_SOFTCORE_DISABLED}" --color "GREEN"
|
|
AddHP 2 3
|
|
elif [ "${FIND1}" = "soft core enabled" ] || [ "${FIND2}" = "hard core enabled" ]; then
|
|
LogText "Result: core dumps are partially enabled ('hard'=${IS_HARDCORE_DISABLED}, 'soft'=${IS_SOFTCORE_DISABLED})"
|
|
Display --indent 4 --text "- 'hard' configuration in ${DIR}etc/security/limits.conf" --result "${IS_HARDCORE_DISABLED}" --color "$(if [ "${IS_HARDCORE_DISABLED}" = "ENABLED" ]; then ${ECHOCMD} RED; elif [ "${IS_HARDCORE_DISABLED}" = "DISABLED" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)"
|
|
Display --indent 4 --text "- 'soft' configuration in ${DIR}etc/security/limits.conf" --result "${IS_SOFTCORE_DISABLED}" --color "$(if [ "${IS_SOFTCORE_DISABLED}" = "ENABLED" ]; then ${ECHOCMD} RED; elif [ "${IS_SOFTCORE_DISABLED}" = "DISABLED" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)"
|
|
AddHP 0 3
|
|
else
|
|
LogText "Result: core dumps are not explicitly disabled"
|
|
Display --indent 4 --text "- 'hard' configuration in ${DIR}etc/security/limits.conf" --result "${IS_HARDCORE_DISABLED}" --color "WHITE"
|
|
Display --indent 4 --text "- 'soft' configuration in ${DIR}etc/security/limits.conf" --result "${IS_HARDCORE_DISABLED}" --color "WHITE"
|
|
ReportSuggestion "${TEST_NO}" "If not required, consider explicit disabling of core dump in ${DIR}etc/security/limits.conf file"
|
|
AddHP 1 3
|
|
fi
|
|
else
|
|
LogText "Result: file ${DIR}etc/security/limits.conf does not exist, skipping test for this file"
|
|
fi
|
|
done
|
|
|
|
# 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 "${STATUS_PROTECTED}" --color WHITE
|
|
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 "${STATUS_DEBUG}" --color YELLOW
|
|
ReportSuggestion "${TEST_NO}" "Determine if all binaries need to be able to core dump"
|
|
AddHP 0 1
|
|
else
|
|
# 0 - (default) - traditional behaviour. Any process which has changed privilege levels or is execute only will not be dumped
|
|
# https://www.kernel.org/doc/Documentation/sysctl/fs.txt
|
|
LogText "Result: found default option (0), no execute only program or program with changed privilege levels can dump"
|
|
Display --indent 4 --text "- Checking setuid core dumps configuration" --result "${STATUS_DISABLED}" --color GREEN
|
|
AddHP 1 1
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : KRNL-5830
|
|
# Description : Check if system needs a reboot (Linux only)
|
|
Register --test-no KRNL-5830 --os Linux --weight L --network NO --category security --description "Checking if system is running on the latest installed kernel"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
REBOOT_NEEDED=2
|
|
for FILE in "${ROOTDIR}var/run/reboot-required.pkgs" "${ROOTDIR}var/run/needs_restarting"
|
|
do
|
|
LogText "Test: Checking presence ${FILE}"
|
|
if [ -f ${FILE} ]; then
|
|
LogText "Result: file ${FILE} exists"
|
|
FIND=$(${WCBINARY} -l < ${FILE})
|
|
if [ "${FIND}" = "0" ]; then
|
|
LogText "Result: No reboot needed (file empty)"
|
|
REBOOT_NEEDED=0
|
|
break
|
|
else
|
|
PKGSCOUNT=$(${WCBINARY} -l < ${FILE})
|
|
LogText "Result: reboot is needed, related to ${PKGSCOUNT} packages"
|
|
for I in ${FIND}; do
|
|
LogText "Package: ${I}"
|
|
done
|
|
REBOOT_NEEDED=1
|
|
break
|
|
fi
|
|
else
|
|
LogText "Result: file ${FILE} not found"
|
|
fi
|
|
done
|
|
|
|
# Check if /boot exists
|
|
if [ -d "${ROOTDIR}boot" ]; then
|
|
LogText "Result: /boot exists, performing more tests from here"
|
|
FIND=$(${LSBINARY} ${ROOTDIR}boot/* 2> /dev/null)
|
|
if [ -n "${FIND}" ]; then
|
|
if [ -f ${ROOTDIR}boot/vmlinuz -a ! -L ${ROOTDIR}boot/vmlinuz ]; then
|
|
LogText "Result: found /boot/vmlinuz (not symlinked)"
|
|
NEXTLINE=0
|
|
FINDVERSION=""
|
|
for I in $(file ${ROOTDIR}boot/vmlinuz-linux); do
|
|
if [ ${NEXTLINE} -eq 1 ]; then
|
|
FINDVERSION="${I}"
|
|
break
|
|
else
|
|
# Searching for the Linux kernel after the keyword 'version'
|
|
if [ "${I}" = "version" ]; then NEXTLINE=1; fi
|
|
fi
|
|
done
|
|
if [ -n "${FINDVERSION}" ]; then
|
|
CURRENT_KERNEL=$(uname -r)
|
|
if [ ! "${CURRENT_KERNEL}" = "${FINDVERSION}" ]; then
|
|
LogText "Result: reboot needed, as current kernel is different than the one loaded"
|
|
REBOOT_NEEDED=1
|
|
fi
|
|
else
|
|
ReportException "${TEST_NO}:1" "Can't determine kernel version on disk, need debug data"
|
|
fi
|
|
elif [ -f ${ROOTDIR}boot/vmlinuz-linux ] || [ -f ${ROOTDIR}boot/vmlinuz-linux-lts ] || [ -f "$(${LSBINARY} -t ${ROOTDIR}boot/vm[l0-9]* 2> /dev/null | ${HEADBINARY} -1)" ]; then
|
|
if [ -f ${ROOTDIR}boot/vmlinuz ]; then
|
|
LogText "Result: found ${ROOTDIR}boot/vmlinuz"
|
|
FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz
|
|
elif [ -f ${ROOTDIR}boot/vmlinuz-linux ]; then
|
|
LogText "Result: found ${ROOTDIR}boot/vmlinuz-linux"
|
|
FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-linux
|
|
elif [ -f ${ROOTDIR}boot/vmlinuz-linux-lts ]; then
|
|
LogText "Result: found ${ROOTDIR}boot/vmlinuz-linux-lts"
|
|
FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-linux-lts
|
|
elif [ -f ${ROOTDIR}boot/vmlinuz-lts ]; then
|
|
LogText "Result: found ${ROOTDIR}boot/vmlinuz-lts"
|
|
FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-lts
|
|
else
|
|
# Match on items like /boot/vm5.3.7 or /boot/vmlinuz-5.3.7-1-default. Sort based on versions (-v) and then find the last item
|
|
# Note: ignore a rescue kernel (e.g. CentOS)
|
|
FOUND_VMLINUZ=$(${LSBINARY} -v ${ROOTDIR}boot/vm[l0-9]* 2> /dev/null | ${GREPBINARY} -v '\-rescue-' | ${TAILBINARY} -1)
|
|
LogText "Result: found ${FOUND_VMLINUZ}"
|
|
fi
|
|
|
|
VERSION_ON_DISK=""
|
|
if [ -L "${FOUND_VMLINUZ}" ]; then
|
|
LogText "Result: found a symlink, retrieving destination"
|
|
FOUND_VMLINUZ=$(readlink "${FOUND_VMLINUZ}")
|
|
LogText "Result: destination file is ${FOUND_VMLINUZ}"
|
|
VERSION_ON_DISK=$(echo ${FOUND_VMLINUZ} | ${SEDBINARY} 's#^/boot/##' | ${SEDBINARY} 's/^vmlinuz-//')
|
|
LogText "Result: version derived from file name is '${VERSION_ON_DISK}'"
|
|
elif [ -f "${FOUND_VMLINUZ}" ]; then
|
|
VERSION_ON_DISK=$(echo ${FOUND_VMLINUZ} | ${SEDBINARY} 's#^/boot/##' | ${SEDBINARY} 's/^vmlinuz-//' | ${SEDBINARY} '$s/-\?\(linux\)\?-\?\(lts\)\?//')
|
|
LogText "Result: version derived from file name is '${VERSION_ON_DISK}'"
|
|
|
|
fi
|
|
|
|
# Data check: perform reset if we found a version but looks incomplete
|
|
# Example: Arch Linux will return only 'linux' as its version after it discovered /boot/vmlinuz-linux
|
|
case ${VERSION_ON_DISK} in
|
|
"linux" | "linux-lts")
|
|
LogText "Result: reset of version (${VERSION_ON_DISK}) as it looks incomplete"
|
|
VERSION_ON_DISK=""
|
|
;;
|
|
esac
|
|
|
|
# If we did not find the version yet, see if we can extract it from the magic data that 'file' returns
|
|
if [ -z "${VERSION_ON_DISK}" ]; then
|
|
LogText "Test: checking kernel version on disk"
|
|
NEXTLINE=0
|
|
VERSION_ON_DISK=""
|
|
for I in $(file ${FOUND_VMLINUZ}); do
|
|
if [ ${NEXTLINE} -eq 1 ]; then
|
|
VERSION_ON_DISK="${I}"
|
|
break
|
|
else
|
|
# Searching for the Linux kernel after the keyword 'version'
|
|
if [ "${I}" = "version" ]; then NEXTLINE=1; fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Last check if we finally got a version or not
|
|
if [ -z "${VERSION_ON_DISK}" ]; then
|
|
LogText "Result: could not find the version on disk"
|
|
ReportException "${TEST_NO}:4" "Could not find the kernel version"
|
|
else
|
|
LogText "Result: found version ${VERSION_ON_DISK}"
|
|
ACTIVE_KERNEL=$(uname -r)
|
|
LogText "Result: active kernel version ${ACTIVE_KERNEL}"
|
|
if [ "${VERSION_ON_DISK}" = "${ACTIVE_KERNEL}" ]; then
|
|
REBOOT_NEEDED=0
|
|
LogText "Result: no reboot needed, active kernel is the same version as the one on disk"
|
|
else
|
|
REBOOT_NEEDED=1
|
|
LogText "Result: reboot needed, as there is a difference between active kernel and the one on disk"
|
|
fi
|
|
fi
|
|
else
|
|
if [ -L ${ROOTDIR}boot/vmlinuz ]; then
|
|
LogText "Result: found symlink of ${ROOTDIR}boot/vmlinuz, skipping file"
|
|
else
|
|
LogText "Result: ${ROOTDIR}boot/vmlinuz not on disk, trying to find ${ROOTDIR}boot/vmlinuz*"
|
|
fi
|
|
# Extra current kernel version and replace dashes to allow numeric ${SORTBINARY} later on
|
|
MYKERNEL=$(${UNAMEBINARY} -r | ${SEDBINARY} 's/\.[a-z].*.//g' | ${SEDBINARY} 's/-[a-z].*.//g' | ${SEDBINARY} 's/-/./g')
|
|
LogText "Result: using ${MYKERNEL} as my kernel version (stripped)"
|
|
FIND=$(ls ${ROOTDIR}boot/vmlinuz* 2> /dev/null)
|
|
if [ -n "${FIND}" ]; then
|
|
for ITEM in ${FIND}; do
|
|
LogText "Result: found ${ITEM}"
|
|
done
|
|
# Display kernels, extract version numbers and ${SORTBINARY} them numeric per column (up to 6 numbers)
|
|
# Ignore rescue images. Remove generic. and huge. for Slackware machines
|
|
# TODO: see if this can be simplified using ls -v sorting
|
|
LogText "Action: checking relevant kernels"
|
|
KERNELS=$(${LSBINARY} /boot/vmlinuz* | ${GREPBINARY} -v rescue | ${SEDBINARY} 's/vmlinuz-//' | ${SEDBINARY} 's/generic.//' | ${SEDBINARY} 's/huge.//' | ${SEDBINARY} 's/\.[a-z].*.//g' | ${SEDBINARY} 's/-[a-z].*.//g' | ${SEDBINARY} 's./boot/..' | ${SEDBINARY} 's/-/./g' | ${SORTBINARY} -n -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -t \.)
|
|
KERNELS_ONE_LINE=$(${ECHOCMD} ${KERNELS} | ${TRBINARY} '\n' ' ')
|
|
LogText "Output: ${KERNELS_ONE_LINE}"
|
|
elif [ ! "$(ls ${ROOTDIR}boot/kernel* 2> /dev/null)" = "" ]; then
|
|
LogText "Output: Found a kernel file in ${ROOTDIR}boot"
|
|
# Display kernels, extract version numbers and ${SORTBINARY} them numeric per column (up to 6 numbers)
|
|
# Examples:
|
|
# /boot/kernel-genkernel-x86_64-3.14.14-gentoo
|
|
KERNELS=$(${LSBINARY} ${ROOTDIR}boot/kernel* | ${AWKBINARY} -F- '{ if ($2=="genkernel") { print $4 }}' | ${GREPBINARY} "^[0-9]" | ${SORTBINARY} -n -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -t \.)
|
|
if [ -n "${KERNELS}" ]; then LogText "Output: ${KERNELS}"; fi
|
|
else
|
|
ReportException "${TEST_NO}:2" "Can not find any vmlinuz or kernel files in /boot, which is unexpected"
|
|
fi
|
|
if [ -n "${KERNELS}" ]; then
|
|
FOUND_KERNEL=0
|
|
for I in ${KERNELS}; do
|
|
# Check if we already found a kernel and it is not equal to what we run (e.g. double versions may exist)
|
|
if [ ${FOUND_KERNEL} -eq 1 -a ! "${MYKERNEL}" = "${I}" ]; then
|
|
LogText "Result: found a kernel (${I}) later than active kernel (${MYKERNEL})"
|
|
REBOOT_NEEDED=1
|
|
fi
|
|
if [ "${MYKERNEL}" = "${I}" ]; then
|
|
FOUND_KERNEL=1
|
|
LogText "Result: found ${I} (= active kernel)"
|
|
else
|
|
LogText "Result: found ${I}"
|
|
fi
|
|
done
|
|
# Check if we at least found the kernel on disk
|
|
if [ ${FOUND_KERNEL} -eq 0 ]; then
|
|
ReportException "${TEST_NO}:3" "Could not find our running kernel on disk, which is unexpected"
|
|
else
|
|
# If we are not sure yet reboot it needed, but we found running kernel as last one on disk, we run latest kernel
|
|
if [ ${REBOOT_NEEDED} -eq 2 ]; then
|
|
LogText "Result: found the running kernel on disk being the last entry, so it looks up-to-date"
|
|
REBOOT_NEEDED=0
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
# No files in /boot
|
|
else
|
|
LogText "Result: Skipping this test, as there are no files in /boot"
|
|
fi
|
|
else
|
|
LogText "Result: /boot does not exist or not privileged to read files"
|
|
fi
|
|
|
|
# Attempt to check for Raspbian if reboot is needed
|
|
# This check searches for apt package "raspberrypi-kernel-[package-date]", trys to extract the date of packaging from the filename
|
|
# and compares that date with the currently running kernel's build date (uname -v).
|
|
# Of course there can be a time difference between kernel build and kernel packaging, therefore a time difference of
|
|
# 3 days is accepted and it is assumed with only 3 days apart, this must be the same kernel version.
|
|
if [ ${REBOOT_NEEDED} -eq 2 ] && [ -d "${APT_ARCHIVE_DIRECTORY}" ]; then
|
|
LogText "Result: found folder ${APT_ARCHIVE_DIRECTORY}; assuming this is a debian based distribution"
|
|
LogText "Check: try to find raspberrypi-kernel file in ${APT_ARCHIVE_DIRECTORY} and extract package date from file name"
|
|
|
|
FOUND_KERNEL_DATE=$(${FINDBINARY} ${APT_ARCHIVE_DIRECTORY} -name "raspberrypi-kernel*" -printf "%T@ %Tc %p\n" 2> /dev/null \
|
|
| ${SORTBINARY} -nr | ${HEADBINARY} -1 | ${GREPBINARY} -o "raspberrypi-kernel.*deb" | ${GREPBINARY} -E -o "\.[0-9]+" | ${SEDBINARY} 's/\.//g')
|
|
|
|
if [ -n "${FOUND_KERNEL_DATE}" ]; then
|
|
FOUND_KERNEL_IN_SECONDS=$(date -d "${FOUND_KERNEL_DATE}" "+%s" 2> /dev/null)
|
|
else
|
|
LogText "Result: Skipping this test, as there was no package date to extract"
|
|
fi
|
|
|
|
if [ -n "${FOUND_KERNEL_IN_SECONDS}" ] && [ ${FOUND_KERNEL_IN_SECONDS} -gt 1 ]; then
|
|
LogText "Result: Got package date: ${FOUND_KERNEL_DATE} (= ${FOUND_KERNEL_IN_SECONDS} seconds)"
|
|
UNAME_OUTPUT="$(${UNAMEBINARY} -v 2> /dev/null)"
|
|
else
|
|
LogText "Result: Skipping this test, as extracting the seconds of package date failed"
|
|
fi
|
|
|
|
if [ -n "${UNAME_OUTPUT}" ]; then
|
|
LogText "Result: Got an output from 'uname -v'"
|
|
LogText "Check: Trying to extract kernel build date from 'uname -v' output"
|
|
next=""
|
|
for part in ${UNAME_OUTPUT}; do
|
|
if [ -z "$next" ]; then
|
|
if [ "${part}" = "Mon" ] || [ "${part}" = "Tue" ] || [ "${part}" = "Wed" ] || [ "${part}" = "Thu" ] || [ "${part}" = "Fri" ] || [ "${part}" = "Sat" ] || [ "${part}" = "Sun" ]; then
|
|
next="month"
|
|
fi
|
|
elif [ "$next" = "month" ]; then
|
|
if [ $(${ECHOCMD} "${part}" | ${GREPBINARY} -E -c "[A-Z][a-z]") -ge 1 ]; then
|
|
UNAME_DATE_MONTH="${part}"
|
|
next="day"
|
|
fi
|
|
elif [ "${next}" = "day" ]; then
|
|
if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c "[0-9][0-9]") -ge 1 ]; then
|
|
UNAME_DATE_DAY="${part}"
|
|
next="time"
|
|
fi
|
|
elif [ "${next}" = "time" ]; then
|
|
if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c ":[0-9][0-9]:") -ge 1 ]; then
|
|
next="year"
|
|
fi
|
|
elif [ "${next}" = "year" ]; then
|
|
if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c "[0-9][0-9]") -ge 1 ]; then
|
|
UNAME_DATE_YEAR="${part}"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
if [ -n "${UNAME_DATE_MONTH}" ] && [ -n "${UNAME_DATE_DAY}" ] && [ -n "${UNAME_DATE_YEAR}" ]; then
|
|
LogText "Result: Extracted kernel build date is: ${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}"
|
|
UNAME_DATE_IN_SECONDS=$(date -d "${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}" "+%s" 2> /dev/null)
|
|
LogText "Check: Comparing kernel build date in seconds (${UNAME_DATE_IN_SECONDS}s) with package date in seconds (${FOUND_KERNEL_IN_SECONDS}s)"
|
|
if [ -n "${UNAME_DATE_IN_SECONDS}" ] && [ ${FOUND_KERNEL_IN_SECONDS} -ge ${UNAME_DATE_IN_SECONDS} ]; then
|
|
LogText "Result: package creation date is older than running kernel. Hence, this check should be valid."
|
|
LogText "Check if package create date and kernel build date are not more than 3 days apart."
|
|
|
|
SECONDS_APART=$(( ${FOUND_KERNEL_IN_SECONDS} - ${UNAME_DATE_IN_SECONDS} ))
|
|
if [ ${SECONDS_APART} -ge 60 ]; then
|
|
MINUTES_APART=$(( ${SECONDS_APART} / 60 ))
|
|
if [ ${MINUTES_APART} -ge 60 ]; then
|
|
DAYS_APART=$(( ${MINUTES_APART} / 60 ))
|
|
if [ ${DAYS_APART} -ge 24 ]; then DAYS_APART=$(( ${DAYS_APART} / 24 )); else DAYS_APART=0; fi
|
|
else
|
|
DAYS_APART=0
|
|
fi
|
|
else
|
|
DAYS_APART=0
|
|
fi
|
|
# assuming kernels are packaged definitely within 3 days. ACCEPTED_TIME_DIFF needs a value in seconds
|
|
ACCEPTED_TIME_DIFF=$((3 * 24 * 60 * 60))
|
|
if [ ${FOUND_KERNEL_IN_SECONDS} -le $((${UNAME_DATE_IN_SECONDS} + ${ACCEPTED_TIME_DIFF})) ]; then
|
|
LogText "Result: package create date and kernel build date are only ${DAYS_APART} day(s) apart."
|
|
LogText "Result: Assuming no reboot needed."
|
|
REBOOT_NEEDED=0
|
|
else
|
|
LogText "Result: package create date and kernel build date are ${DAYS_APART} day(s) apart."
|
|
LogText "Result: Assuming reboot is needed."
|
|
REBOOT_NEEDED=1
|
|
fi
|
|
else
|
|
LogText "Result: Package's create date is older than running kernel, which is unexpected. Might not be a valid test. Skipping..."
|
|
fi
|
|
else
|
|
LogText "Result: Could not extract Day, Month and Year from 'uname -v' output"
|
|
fi
|
|
else
|
|
LogText "Result: Did not get output from 'uname -v'. Skipping test."
|
|
fi
|
|
|
|
else
|
|
LogText "Result: /var/cache/apt/archives/ does not exist"
|
|
fi
|
|
|
|
# Display discovered status
|
|
if [ ${REBOOT_NEEDED} -eq 0 ]; then
|
|
Display --indent 2 --text "- Check if reboot is needed" --result "${STATUS_NO}" --color GREEN
|
|
AddHP 5 5
|
|
elif [ ${REBOOT_NEEDED} -eq 1 ]; then
|
|
Display --indent 2 --text "- Check if reboot is needed" --result "${STATUS_YES}" --color RED
|
|
ReportWarning "${TEST_NO}" "Reboot of system is most likely needed" "" "text:reboot"
|
|
AddHP 0 5
|
|
else
|
|
Display --indent 2 --text "- Check if reboot is needed" --result "${STATUS_UNKNOWN}" --color YELLOW
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
|
|
WaitForKeyPress
|
|
|
|
#
|
|
#================================================================================
|
|
# Lynis - Copyright 2007-2021, CISOfy - https://cisofy.com
|