mirror of https://github.com/CISOfy/lynis.git
286 lines
13 KiB
Bash
286 lines
13 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.
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Shells
|
|
#
|
|
#################################################################################
|
|
#
|
|
IDLE_TIMEOUT=0
|
|
InsertSection "${SECTION_SHELLS}"
|
|
#
|
|
#################################################################################
|
|
#
|
|
# bash
|
|
# Files (interactive login shells): /etc/profile $HOME/.bash_profile
|
|
# $HOME/.bash_login $HOME/.profile
|
|
# Files (interactive non-login shells): $HOME/.bash_rc
|
|
#
|
|
# csh/tcsh
|
|
# Files: /etc/csh.cshrc /etc/csh.login
|
|
#
|
|
# zsh
|
|
# Files: /etc/zshenv /etc/zsh/zshenv $HOME/.zshenv /etc/zprofile
|
|
# /etc/zsh/zprofile $HOME/.zprofile /etc/zshrc /etc/zsh/zshrc
|
|
# $ZDOTDIR/.zshrc /etc/zlogin /etc/zsh/zlogin
|
|
|
|
SHELL_LOGIN_FILES="${ROOTDIR}etc/csh.cshrc ${ROOTDIR}etc/csh.login ${ROOTDIR}etc/zshenv ${ROOTDIR}etc/zsh/zshenv
|
|
${ROOTDIR}etc/zprofile ${ROOTDIR}etc/zsh/zprofile ${ROOTDIR}etc/zshrc ${ROOTDIR}etc/zsh/zshrc
|
|
${ROOTDIR}etc/zlogin ${ROOTDIR}etc/zsh/zlogin"
|
|
#
|
|
#################################################################################
|
|
#
|
|
|
|
# Test : SHLL-6202
|
|
# Description : check all console TTYs in which root user can enter single user mode without password
|
|
Register --test-no SHLL-6202 --os FreeBSD --weight L --network NO --category security --description "Check console TTYs"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
LogText "Test: Checking console TTYs"
|
|
FIND=$(${EGREPBINARY} '^console' ${ROOTDIR}etc/ttys | ${GREPBINARY} -v 'insecure')
|
|
if [ -z "${FIND}" ]; then
|
|
Display --indent 2 --text "- Checking console TTYs" --result "${STATUS_OK}" --color GREEN
|
|
LogText "Result: console is secured against single user mode without password."
|
|
else
|
|
Display --indent 2 --text "- Checking console TTYs" --result "${STATUS_WARNING}" --color RED
|
|
LogText "Result: Found insecure console in ${ROOTDIR}etc/ttys. Single user mode login without password allowed!"
|
|
LogText "Output ${ROOTDIR}etc/ttys:"
|
|
LogText "${FIND}"
|
|
ReportWarning "${TEST_NO}" "Found unprotected console in ${ROOTDIR}etc/ttys"
|
|
LogText "Possible solution: Change the console line from 'secure' to 'insecure'."
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : SHLL-6211
|
|
# Description : Determine available shell according /etc/shells
|
|
Register --test-no SHLL-6211 --weight L --network NO --category security --description "Available and valid shells"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
LogText "Test: Searching for ${ROOTDIR}etc/shells"
|
|
if [ -f ${ROOTDIR}etc/shells ]; then
|
|
LogText "Result: Found ${ROOTDIR}etc/shells file"
|
|
LogText "Test: Reading available shells from ${ROOTDIR}etc/shells"
|
|
SSHELLS=$(${GREPBINARY} "^/" ${ROOTDIR}etc/shells)
|
|
CSSHELLS=0; CSSHELLS_ALL=0
|
|
Display --indent 2 --text "- Checking shells from ${ROOTDIR}etc/shells"
|
|
for I in ${SSHELLS}; do
|
|
CSSHELLS_ALL=$((CSSHELLS_ALL + 1))
|
|
Report "available_shell[]=${I}"
|
|
# TODO add check for symlinked shells
|
|
if [ -f ${I} ]; then
|
|
LogText "Found installed shell: ${I}"
|
|
CSSHELLS=$((CSSHELLS + 1))
|
|
else
|
|
LogText "Shell ${I} not installed. Probably a dummy or non existing shell."
|
|
fi
|
|
done
|
|
Display --indent 4 --text "Result: found ${CSSHELLS_ALL} shells (valid shells: ${CSSHELLS})."
|
|
else
|
|
LogText "Result: ${ROOTDIR}etc/shells not found, skipping test"
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : SHLL-6220
|
|
# Description : Check for idle session killing tools or settings
|
|
Register --test-no SHLL-6220 --weight L --network NO --category security --description "Idle session killing tools or settings"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
|
|
IDLE_TIMEOUT_METHOD=""
|
|
IDLE_TIMEOUT_READONLY=""
|
|
|
|
LogText "Test: Search for session timeout tools or settings in shell"
|
|
if IsRunning "timeoutd"; then
|
|
IDLE_TIMEOUT=1
|
|
LogText "Result: found timeoutd process to kill idle sessions"
|
|
IDLE_TIMEOUT_METHOD="timeout-daemon"
|
|
fi
|
|
if IsRunning "autolog"; then
|
|
IDLE_TIMEOUT=1
|
|
LogText "Result: found autolog process to kill idle sessions"
|
|
Report "session_timeout_method[]=autolog"
|
|
IDLE_TIMEOUT_METHOD="autolog"
|
|
fi
|
|
|
|
if [ -f ${ROOTDIR}etc/profile ]; then
|
|
# Determine if we can find a TMOUT value
|
|
FIND=$(${GREPBINARY} 'TMOUT=' ${ROOTDIR}etc/profile | ${TRBINARY} -d ' ' | ${TRBINARY} -d '\t' | ${GREPBINARY} -v "^#" | ${SEDBINARY} 's/export//' | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} -F= '{ print $2 }')
|
|
# Determine if the value is exported (with export, readonly, or typeset)
|
|
FIND2=$(${GREPBINARY} '\(export\|readonly\|typeset -r\)[ \t]*TMOUT' ${ROOTDIR}etc/profile | ${GREPBINARY} -v "^#" | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} '{ print $1 }')
|
|
if [ -n "${FIND}" ]; then
|
|
N=0; IDLE_TIMEOUT=1
|
|
for I in ${FIND}; do
|
|
LogText "Output: ${I}"
|
|
Report "session_timeout_value[]=${I}"
|
|
N=$((N + 1))
|
|
done
|
|
if [ ${N} -eq 1 ]; then
|
|
LogText "Result: found TMOUT value configured in ${ROOTDIR}etc/profile"
|
|
else
|
|
LogText "Result: found several TMOUT values configured in ${ROOTDIR}etc/profile"
|
|
fi
|
|
IDLE_TIMEOUT_METHOD="profile"
|
|
else
|
|
LogText "Result: could not find TMOUT setting in ${ROOTDIR}etc/profile"
|
|
fi
|
|
|
|
if [ -n "${FIND2}" ]; then
|
|
N=0;
|
|
for I in ${FIND2}; do
|
|
LogText "Output: ${I}"
|
|
if [ "${I}" = "readonly" -o "${I}" = "typeset" ]; then
|
|
N=$((N + 1))
|
|
fi
|
|
done
|
|
if [ ${N} -gt 0 ]; then
|
|
LogText "Result: found readonly setting in ${ROOTDIR}etc/profile (readonly or typeset -r)"
|
|
IDLE_TIMEOUT_READONLY=1
|
|
else
|
|
LogText "Result: NO readonly setting found in ${ROOTDIR}etc/profile (readonly or typeset -r)"
|
|
IDLE_TIMEOUT_READONLY=0
|
|
fi
|
|
else
|
|
LogText "Result: could not find export, readonly or typeset -r in ${ROOTDIR}etc/profile"
|
|
fi
|
|
else
|
|
LogText "Result: skip ${ROOTDIR}etc/profile test, file not available on this system"
|
|
fi
|
|
|
|
if [ -d ${ROOTDIR}etc/profile.d ]; then
|
|
FIND=$(${LSBINARY} ${ROOTDIR}etc/profile.d/*.sh 2> /dev/null)
|
|
if [ -n "${FIND}" ]; then
|
|
# Determine if we can find a TMOUT value
|
|
FIND=$(${FINDBINARY} ${ROOTDIR}etc/profile.d -name "*.sh" -type f -exec cat {} \; 2> /dev/null | ${GREPBINARY} 'TMOUT=' | ${TRBINARY} -d ' ' | ${TRBINARY} -d '\t' | ${GREPBINARY} -v "^#" | ${SEDBINARY} 's/export//' | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} -F= '{ print $2 }')
|
|
# Determine if the value is exported (with export, readonly, or typeset)
|
|
FIND2=$(${FINDBINARY} ${ROOTDIR}etc/profile.d -name "*.sh" -type f -exec cat {} \; 2> /dev/null | ${GREPBINARY} '\(export\|readonly\|typeset -r\)[ \t]*TMOUT' | ${GREPBINARY} -v "^#" | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} '{ print $1 }')
|
|
if [ -n "${FIND}" ]; then
|
|
N=0; IDLE_TIMEOUT=1
|
|
for I in ${FIND}; do
|
|
LogText "Output: ${I}"
|
|
Report "session_timeout_value[]=${I}"
|
|
N=$((N + 1))
|
|
done
|
|
if [ ${N} -eq 1 ]; then
|
|
LogText "Result: found TMOUT value configured in one of the files in ${ROOTDIR}etc/profile.d directory"
|
|
else
|
|
LogText "Result: found several TMOUT values configured in one of the files in ${ROOTDIR}etc/profile.d directory"
|
|
fi
|
|
IDLE_TIMEOUT_METHOD="profile.d"
|
|
else
|
|
LogText "Result: could not find TMOUT setting in ${ROOTDIR}etc/profile.d/*.sh"
|
|
fi
|
|
# Check for readonly
|
|
if [ -n "${FIND2}" ]; then
|
|
N=0;
|
|
for I in ${FIND2}; do
|
|
LogText "Output: ${I}"
|
|
if [ "${I}" = "readonly" -o "${I}" = "typeset" ]; then
|
|
N=$((N + 1))
|
|
fi
|
|
done
|
|
if [ ${N} -gt 0 ]; then
|
|
LogText "Result: found readonly setting in ${ROOTDIR}etc/profile (readonly or typeset -r)"
|
|
IDLE_TIMEOUT_READONLY=1
|
|
else
|
|
LogText "Result: NO readonly setting found in ${ROOTDIR}etc/profile (readonly or typeset -r)"
|
|
IDLE_TIMEOUT_READONLY=0
|
|
fi
|
|
else
|
|
LogText "Result: could not find export, readonly or typeset -r in ${ROOTDIR}etc/profile"
|
|
fi
|
|
fi
|
|
else
|
|
LogText "Result: skip ${ROOTDIR}etc/profile.d directory test, directory not available on this system"
|
|
fi
|
|
|
|
if [ -n "${IDLE_TIMEOUT_METHOD}" ]; then
|
|
Report "session_timeout_method[]=${IDLE_TIMEOUT_METHOD}"
|
|
fi
|
|
if [ -n "${IDLE_TIMEOUT_READONLY}" ]; then
|
|
Report "session_timeout_set_readonly=${IDLE_TIMEOUT_READONLY}"
|
|
fi
|
|
|
|
if [ ${IDLE_TIMEOUT} -eq 1 ]; then
|
|
Display --indent 4 --text "- Session timeout settings/tools" --result "${STATUS_FOUND}" --color GREEN
|
|
AddHP 3 3
|
|
else
|
|
Display --indent 4 --text "- Session timeout settings/tools" --result "${STATUS_NONE}" --color YELLOW
|
|
AddHP 1 3
|
|
fi
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
# Test : SHLL-6230
|
|
# Description : Check for umask values in shell configurations
|
|
SHELL_CONFIG_FILES="${ROOTDIR}etc/bashrc ${ROOTDIR}etc/bash.bashrc ${ROOTDIR}etc/bash.bashrc.local ${ROOTDIR}etc/csh.cshrc ${ROOTDIR}etc/profile"
|
|
Register --test-no SHLL-6230 --weight H --network NO --category security --description "Perform umask check for shell configurations"
|
|
if [ ${SKIPTEST} -eq 0 ]; then
|
|
FOUND=0
|
|
Display --indent 2 --text "- Checking default umask values"
|
|
for FILE in ${SHELL_CONFIG_FILES}; do
|
|
HARDENING_POSSIBLE=0
|
|
FIND=""
|
|
if [ -f ${FILE} ]; then
|
|
LogText "Result: file ${FILE} exists"
|
|
FOUND=1
|
|
FIND=$(${GREPBINARY} umask ${FILE} | ${SEDBINARY} 's/^[ \t]*//g' | ${SEDBINARY} 's/#.*$//' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ print $2 }')
|
|
if IsEmpty "${FIND}"; then
|
|
LogText "Result: did not find umask configured in ${FILE}"
|
|
Display --indent 4 --text "- Checking default umask in ${FILE}" --result "${STATUS_NONE}" --color YELLOW
|
|
else
|
|
for UMASKVALUE in ${FIND}; do
|
|
LogText "Result: found umask ${UMASKVALUE} in ${FILE}"
|
|
case ${UMASKVALUE} in
|
|
027|0027|077|0077)
|
|
LogText "Result: umask ${UMASKVALUE} is considered a properly hardened value"
|
|
;;
|
|
*)
|
|
LogText "Result: umask ${UMASKVALUE} can be hardened "
|
|
HARDENING_POSSIBLE=1
|
|
;;
|
|
esac
|
|
done
|
|
if [ ${HARDENING_POSSIBLE} -eq 0 ]; then
|
|
Display --indent 4 --text "- Checking default umask in ${FILE}" --result "${STATUS_OK}" --color GREEN
|
|
AddHP 3 3
|
|
else
|
|
Display --indent 4 --text "- Checking default umask in ${FILE}" --result "${STATUS_WEAK}" --color YELLOW
|
|
AddHP 1 3
|
|
fi
|
|
fi
|
|
else
|
|
LogText "Result: file ${FILE} not found"
|
|
fi
|
|
done
|
|
fi
|
|
#
|
|
#################################################################################
|
|
#
|
|
|
|
Report "session_timeout_enabled=${IDLE_TIMEOUT}"
|
|
|
|
|
|
WaitForKeyPress
|
|
|
|
#
|
|
#================================================================================
|
|
# Lynis - Copyright 2007-2021, CISOfy - http://cisofy.com
|