Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/CISOfy/lynis.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md81
-rw-r--r--db/languages/da41
-rw-r--r--db/software-eol.db24
-rw-r--r--db/tests.db13
-rw-r--r--include/binaries67
-rw-r--r--include/consts8
-rw-r--r--include/functions218
-rw-r--r--include/helper_audit_dockerfile38
-rw-r--r--include/helper_generate89
-rw-r--r--include/helper_show14
-rw-r--r--include/osdetection2
-rw-r--r--include/parameters38
-rw-r--r--include/report114
-rw-r--r--include/tests_authentication48
-rw-r--r--include/tests_boot_services6
-rw-r--r--include/tests_filesystems36
-rw-r--r--include/tests_firewalls5
-rw-r--r--include/tests_insecure_services332
-rw-r--r--include/tests_networking41
-rw-r--r--include/tests_php3
-rw-r--r--include/tests_ports_packages95
-rw-r--r--include/tests_shells11
-rwxr-xr-xlynis30
23 files changed, 1093 insertions, 261 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3522551..0d9a969c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,86 @@
# Lynis Changelog
+## Lynis 3.0.0 (not released yet)
+
+This is a major release of Lynis and includes several big changes.
+Some of these changes may break your current usage of the tool, so test before
+deployment.
+
+Breaking changes:
+- Some of the old and deprecated commands or switches are removed
+
+An important focus area for this release is on security. We added several
+measures to further tighten any possible misuse.
+
+### Added
+- Test PATH and warn or exit on discovery of dangerous location (security)
+- Additional safeguard by testing if common system tools are available (security)
+- Test parameters and arguments for presence of control characters (security)
+- New function SafeInput (security)
+
+### Changed
+- The 'nounset' (set -u) parameter is now activated by default (security)
+- Use locations from PATH environment variable, unless it is empty
+
+---------------------------------------------------------------------------------
+
+## Lynis 2.7.5 (2019-06-24)
+
+### Added
+- Danish translation
+- Slackware end-of-life information
+- Detect BSD-style (rc.d) init in Linux systems
+- Detection of Bro and Suricata (IDS)
+
+### Changed
+- Corrected end-of-life entries for CentOS 5 and 6
+- AUTH-9204 - change name to check in /etc/passwd file for QNAP devices
+- AUTH-9268 - AIX enhancement to use correct find statement
+- FILE-6310 - Filter on correct field for AIX
+- NETW-3012 - set ss command as preferred option for Linux and changed output format
+- List of PHP ini file locations has been extended
+- Removed several pieces of the code as part of cleanup and code health
+- Extended help
+
+---------------------------------------------------------------------------------
+
+
+## Lynis 2.7.4 (2019-04-21)
+
+This is a bigger release than usual, including several new tests created by
+Capashenn (GitHub). It is a coincidence that it is released exactly one month
+after the previous version and on Easter. No easter eggs, only improvements!
+
+### Added
+- FILE-6324 - Discover XFS mount points
+- INSE-8000 - Installed inetd package
+- INSE-8100 - Installed xinetd package
+- INSE-8102 - Status of xinet daemon
+- INSE-8104 - xinetd configuration file
+- INSE-8106 - xinetd configuration for inactive daemon
+- INSE-8200 - Usage of TCP wrappers
+- INSE-8300 - Presence of rsh client
+- INSE-8302 - Presence of rsh server
+- Detect equery binary detection
+- New 'generate' command
+
+### Changed
+- AUTH-9278 - Test LDAP in all PAM components on Red Hat and other systems
+- PKGS-7410 - Add support for DPKG-based systems to gather installed kernel packages
+- PKGS-7420 - Detect toolkit to automatically download and apply upgrades
+- PKGS-7328 - Added global Zypper option --non-interactive
+- PKGS-7330 - Added global Zypper option --non-interactive
+- PKGS-7386 - Only show warning when vulnerable packages were discovered
+- PKGS-7392 - Skip test for Zypper-based systems
+- Minor changes to improve text output, test descriptions, and logging
+- Changed CentOS identifiers in end-of-life database
+- AIX enhancement for IsRunning function
+- Extended PackageIsInstalled function
+- Improve text output on AIX systems
+- Corrected lsvg binary detection
+
+---------------------------------------------------------------------------------
+
## Lynis 2.7.3 (2019-03-21)
### Added
diff --git a/db/languages/da b/db/languages/da
new file mode 100644
index 00000000..d26c1220
--- /dev/null
+++ b/db/languages/da
@@ -0,0 +1,41 @@
+ERROR_NO_LICENSE="Ingen licensnøgle konfigureret"
+ERROR_NO_UPLOAD_SERVER="Ingen upload server konfigureret"
+GEN_CHECKING="Tjekker"
+GEN_CURRENT_VERSION="Nuværende version"
+GEN_DEBUG_MODE="Fejlfindingstilstand"
+GEN_INITIALIZE_PROGRAM="Initialiserer program"
+GEN_LATEST_VERSION="Seneste version"
+GEN_PHASE="Fase"
+GEN_PLUGINS_ENABLED="Plugins aktiverede"
+GEN_UPDATE_AVAILABLE="opdatering tilgængelig"
+GEN_VERBOSE_MODE="Detaljeret tilstand"
+GEN_WHAT_TO_DO="At gøre"
+NOTE_EXCEPTIONS_FOUND="Undtagelser fundet"
+NOTE_EXCEPTIONS_FOUND_DETAILED="Nogle usædvanlige hændelser eller information var fundet"
+NOTE_PLUGINS_TAKE_TIME="Bemærk: plugins har mere omfattende tests og kan tage flere minutter at fuldføre"
+NOTE_SKIPPED_TESTS_NON_PRIVILEGED="Sprang over tests på grund af ikke-privilegeret tilstand"
+SECTION_CUSTOM_TESTS="Brugerdefinerede Tests"
+SECTION_MALWARE="Malware"
+SECTION_MEMORY_AND_PROCESSES="Hukommelse og Processer"
+STATUS_DISABLED="DEAKTIVERET"
+STATUS_DONE="FÆRDIG"
+STATUS_ENABLED="AKTIVERET"
+STATUS_NOT_ENABLED="IKKE AKTIVERET"
+STATUS_ERROR="FEJL"
+STATUS_FOUND="FUNDET"
+STATUS_YES="JA"
+STATUS_NO="NEJ"
+STATUS_OFF="FRA"
+STATUS_OK="OK"
+STATUS_ON="TIL"
+STATUS_NONE="INGEN"
+STATUS_NOT_FOUND="IKKE FUNDET"
+STATUS_NOT_RUNNING="KØRER IKKE"
+STATUS_RUNNING="KØRER"
+STATUS_SKIPPED="SPRUNGET OVER"
+STATUS_SUGGESTION="FORSLAG"
+STATUS_UNKNOWN="UKENDT"
+STATUS_WARNING="ADVARSEL"
+STATUS_WEAK="SVAG"
+TEXT_YOU_CAN_HELP_LOGFILE="Du kan hjælpe ved at bidrage med din logfil"
+TEXT_UPDATE_AVAILABLE="opdatering tilgængelig"
diff --git a/db/software-eol.db b/db/software-eol.db
index 39edb2da..084a5815 100644
--- a/db/software-eol.db
+++ b/db/software-eol.db
@@ -11,9 +11,9 @@
#
# CentOS
#
-os:CentOS 5:2017-03-31:1490911200:
-os:CentOS 6:2020-11-30:1606690800:
-os:CentOS 7:2024-06-30:1719698400:
+os:CentOS release 5:2017-03-31:1490911200:
+os:CentOS release 6:2020-11-30:1606690800:
+os:CentOS Linux release 7:2024-06-30:1719698400:
#
# FreeBSD - https://www.freebsd.org/security/unsupported.html
#
@@ -43,4 +43,20 @@ os:Ubuntu 17.04:2018-01-01:1514761200:
os:Ubuntu 17.10:2018-07-01:1530396000:
os:Ubuntu 18.04:2023-05-01:1682892000:
os:Ubuntu 18.10:2019-07-01:1561932000:
-os:Ubuntu 19.04:2020-01-01:1577833200: \ No newline at end of file
+os:Ubuntu 19.04:2020-01-01:1577833200:
+#
+# Slackware - https://en.wikipedia.org/wiki/Slackware#Releases
+#
+os:Slackware Linux 8.1:2012-08-01:1343768400:
+os:Slackware Linux 9.0:2012-08-01:1343768400:
+os:Slackware Linux 9.1:2012-08-01:1343768400:
+os:Slackware Linux 10.0:2012-08-01:1343768400:
+os:Slackware Linux 10.1:2012-08-01:1343768400:
+os:Slackware Linux 10.2:2012-08-01:1343768400:
+os:Slackware Linux 11.0:2012-08-01:1343768400:
+os:Slackware Linux 12.0:2012-08-01:1343768400:
+os:Slackware Linux 12.1:2013-12-09:1386540000:
+os:Slackware Linux 12.2:2013-12-09:1386540000:
+os:Slackware Linux 13.0:2018-07-05:1530738000:
+os:Slackware Linux 13.1:2018-07-05:1530738000:
+os:Slackware Linux 13.37:2018-07-05:1530738000:
diff --git a/db/tests.db b/db/tests.db
index 641ea927..215c3595 100644
--- a/db/tests.db
+++ b/db/tests.db
@@ -169,11 +169,17 @@ HTTP-6712:test:security:webservers::Check nginx access logging:
HTTP-6714:test:security:webservers::Check for missing error logs in nginx:
HTTP-6716:test:security:webservers::Check for debug mode on error log in nginx:
HTTP-6720:test:security:webservers::Check Nginx log files:
-INSE-8002:test:security:insecure_services::Check for enabled inet daemon:
-INSE-8004:test:security:insecure_services::Check for enabled inet daemon:
-INSE-8006:test:security:insecure_services::Check configuration of inetd when disabled:
+INSE-8000:test:security:insecure_services::Installed inetd package:
+INSE-8002:test:security:insecure_services::Status of inet daemon:
+INSE-8004:test:security:insecure_services::Presence of inetd configuration file:
+INSE-8006:test:security:insecure_services::Check configuration of inetd when it is disabled:
INSE-8016:test:security:insecure_services::Check for telnet via inetd:
INSE-8050:test:security:insecure_services:MacOS:Check for insecure services on macOS systems:
+INSE-8100:test:security:insecure_services::Installed xinetd package:
+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:
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:
@@ -319,6 +325,7 @@ PKGS-7393:test:security:ports_packages::Check for Gentoo vulnerable packages:
PKGS-7394:test:security:ports_packages:Linux:Check for Ubuntu updates:
PKGS-7398:test:security:ports_packages::Check for package audit tool:
PKGS-7410:test:security:ports_packages::Count installed kernel packages:
+PKGS-7420:test:security:ports_packages::Detect toolkit to automatically download and apply upgrades:
PRNT-2302:test:security:printers_spools:FreeBSD:Check for printcap consistency:
PRNT-2304:test:security:printers_spools::Check cupsd status:
PRNT-2306:test:security:printers_spools::Check CUPSd configuration file:
diff --git a/include/binaries b/include/binaries
index 18b54b2a..c3e5dff9 100644
--- a/include/binaries
+++ b/include/binaries
@@ -42,18 +42,39 @@
Display --indent 2 --text "- Checking system binaries..."
LogText "Status: Starting binary scan..."
- # Test if our PATH variable provides a set of paths
- # If so, reverse the order. If we discover the same binary multiple times, the one first in PATH
- # should be used.
- # If PATH is empty, we use the predefined list in include/consts. Common paths first, then followed
- # by more specific paths. This helps on the slightly ancient UNIX derivatives.
+ # Notes:
+ # - If PATH is empty, we use the predefined list in include/consts
+ # - Common paths first, then followed by more specific paths. This helps on the slightly ancient UNIX derivatives.
+ # - Avoid sorting the path list, as this might result in incorrect order of finding binaries (e.g. awk binary)
+
+ # Test if our PATH variable provides a set of paths. If so, reverse the order. If we discover the same binary
+ # multiple times, the one first in PATH should be used.
if [ ! -z "${PATH}" ]; then
PATH_REVERSED=$(echo ${PATH} | awk -F: '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }')
- BIN_PATHS=$(echo "${PATH_REVERSED} ${BIN_PATHS}" | tr ':' ' ')
+ BIN_PATHS=$(echo "${PATH_REVERSED}" | tr ':' ' ')
fi
- # Avoid sorting, as this might result in incorrect order of finding binaries (e.g. awk binary)
- #SORTED_BIN_PATHS=$(echo ${BIN_PATHS} | tr ' ' '\n' | sort | uniq | tr '\n' ' ')
+ # First test available locations that may be suspicious or dangerous
+ for SCANDIR in ${BIN_PATHS}; do
+ FOUND=0
+ if [ "${SCANDIR}" = "." ]; then FOUND=1; MSG="Found single dot (.) in PATH"
+ elif [ "${SCANDIR}" = ".." ]; then FOUND=1; MSG="Found double dot (..) in PATH"
+ elif echo ${SCANDIR} | grep '^\.\.' > /dev/null; then FOUND=1; MSG="Found path starting with double dot (..) in PATH"
+ elif echo ${SCANDIR} | grep '^[a-zA-Z]' > /dev/null; then FOUND=1; MSG="Found relative path in PATH"
+ fi
+ if [ ${FOUND} -eq 1 ]; then
+ # Stop execution if privileged, otherwise continue but warn user
+ if [ ${PRIVILEGED} -eq 1 ]; then
+ ExitFatal "Possible riskful location (${SCANDIR}) in PATH discovered. Quitting..."
+ else
+ Display --indent 4 --text "Warning: suspicious location (${SCANDIR}) in PATH"
+ ReportWarning "${TEST_NO}" "Possible riskful location in PATH discovered" "text:${MSG}"
+ sleep 1
+ fi
+ fi
+ done
+
+ # Now perform binary detection
for SCANDIR in ${BIN_PATHS}; do
LogText "Test: Checking binaries in directory ${SCANDIR}"
ORGPATH=""
@@ -99,6 +120,7 @@
afick.pl) AFICKBINARY=${BINARY}; LogText " Found known binary: afick (file integrity checker) - ${BINARY}" ;;
aide) AIDEBINARY=${BINARY}; LogText " Found known binary: aide (file integrity checker) - ${BINARY}" ;;
apache2) HTTPDBINARY=${BINARY}; LogText " Found known binary: apache2 (web server) - ${BINARY}" ;;
+ apt) APTBINARY=${BINARY}; LogText " Found known binary: apt (package manager) - ${BINARY}" ;;
arch-audit) ARCH_AUDIT_BINARY="${BINARY}"; LogText " Found known binary: arch-audit (auditing utility to test for vulnerable packages) - ${BINARY}" ;;
auditd) AUDITDBINARY=${BINARY}; LogText " Found known binary: auditd (audit framework) - ${BINARY}" ;;
awk) AWKBINARY=${BINARY}; LogText " Found known binary: awk (string tool) - ${BINARY}" ;;
@@ -109,6 +131,7 @@
base64) BASE64BINARY="${BINARY}"; LogText " Found known binary: base64 (encoding tool) - ${BINARY}" ;;
blkid) BLKIDBINARY="${BINARY}"; LogText " Found known binary: blkid (information about block devices) - ${BINARY}" ;;
bootctl) BOOTCTLBINARY="${BINARY}"; LogText " Found known binary: bootctl (systemd-boot manager utility) - ${BINARY}" ;;
+ bro) BROBINARY="${BINARY}"; LogText " Found known binary: bro (IDS) - ${BINARY}" ;;
cat) CAT_BINARY="${BINARY}"; LogText " Found known binary: cat (generic file handling) - ${BINARY}" ;;
cc) CCBINARY="${BINARY}"; COMPILER_INSTALLED=1; LogText " Found known binary: cc (compiler) - ${BINARY}" ;;
chkconfig) CHKCONFIGBINARY=${BINARY}; LogText " Found known binary: chkconfig (administration tool) - ${BINARY}" ;;
@@ -131,7 +154,8 @@
domainname) DOMAINNAMEBINARY="${BINARY}"; LogText " Found known binary: domainname (NIS domain) - ${BINARY}" ;;
dpkg) DPKGBINARY="${BINARY}"; LogText " Found known binary: dpkg (package management) - ${BINARY}" ;;
egrep) EGREPBINARY=${BINARY}; LogText " Found known binary: egrep (text search) - ${BINARY}" ;;
- exim) EXIMBINARY="${BINARY}"; EXIMVERSION=$(${BINARY} -bV | grep 'Exim version' | awk '{ print $3 }' | xargs); LogText "Found ${BINARY} (version ${EXIMVERSION})" ;;
+ equery) EQUERYBINARY="${BINARY}"; LogText " Found known binary: query (package manager) - ${BINARY}" ;;
+ exim) EXIMBINARY="${BINARY}"; EXIMVERSION=$(${BINARY} -bV | grep 'Exim version' | awk '{ print $3 }' | xargs); LogText " Found known binary ${BINARY} (version ${EXIMVERSION})" ;;
fail2ban-server) FAIL2BANBINARY="${BINARY}"; LogText " Found known binary: fail2ban (IPS tool) - ${BINARY}" ;;
file) FILEBINARY="${BINARY}"; LogText " Found known binary: file (file type detection) - ${BINARY}" ;;
find) FINDBINARY="${BINARY}"; LogText " Found known binary: find (search tool) - ${BINARY}" ;;
@@ -164,7 +188,7 @@
lsattr) LSATTRBINARY="${BINARY}"; LogText " Found known binary: lsattr (file attributes) - ${BINARY}" ;;
lsmod) LSMODBINARY="${BINARY}"; LogText " Found known binary: lsmod (kernel modules) - ${BINARY}" ;;
lsof) LSOFBINARY="${BINARY}"; LogText " Found known binary: lsof (open files) - ${BINARY}" ;;
- lsvg) LVSGBINARY=${BINARY}; LogText " Found known binary: lsvg (volume manager) - ${BINARY}" ;;
+ lsvg) LSVGBINARY=${BINARY}; LogText " Found known binary: lsvg (volume manager) - ${BINARY}" ;;
lvdisplay) LVDISPLAYBINARY="${BINARY}"; LogText " Found known binary: lvdisplay (LVM tool) - ${BINARY}" ;;
lynx) LYNXBINARY="${BINARY}"; LYNXVERSION=$(${BINARY} -version | grep "^Lynx Version" | cut -d ' ' -f3); LogText "Found known binary: lynx (browser) - ${BINARY} (version ${LYNXVERSION})" ;;
maldet) LMDBINARY="${BINARY}"; MALWARE_SCANNER_INSTALLED=1; LogText " Found known binary: maldet (Linux Malware Detect, malware scanner) - ${BINARY}" ;;
@@ -225,6 +249,7 @@
sha1|sha1sum|shasum) SHA1SUMBINARY="${BINARY}"; LogText " Found known binary: sha1/sha1sum/shasum (crypto hashing) - ${BINARY}" ;;
sha256|sha256sum) SHA256SUMBINARY="${BINARY}"; LogText " Found known binary: sha256/sha256sum (crypto hashing) - ${BINARY}" ;;
ssh-keyscan) SSHKEYSCANBINARY="${BINARY}"; LogText " Found known binary: ssh-keyscan (scanner for SSH keys) - ${BINARY}" ;;
+ suricata) SURICATABINARY="${BINARY}"; LogText " Found known binary: suricata (IDS) - ${BINARY}" ;;
sysctl) SYSCTLBINARY="${BINARY}"; LogText " Found known binary: sysctl (kernel parameters) - ${BINARY}" ;;
syslog-ng) SYSLOGNGBINARY="${BINARY}"; SYSLOGNGVERSION=$(${BINARY} -V 2>&1 | grep "^syslog-ng" | awk '{ print $2 }'); LogText "Found ${BINARY} (version ${SYSLOGNGVERSION})" ;;
systemctl) SYSTEMCTLBINARY="${BINARY}"; LogText " Found known binary: systemctl (client to systemd) - ${BINARY}" ;;
@@ -265,6 +290,28 @@
LogText "Result: checking of binaries skipped in this mode"
fi
+ # Test if the basic system tools are defined. These will be used during the audit.
+ [ "${AWKBINARY:-}" ] || ExitFatal "awk binary not found"
+ [ "${CUTBINARY:-}" ] || ExitFatal "cut binary not found"
+ [ "${EGREPBINARY:-}" ] || ExitFatal "grep binary not found"
+ [ "${FINDBINARY:-}" ] || ExitFatal "find binary not found"
+ [ "${GREPBINARY:-}" ] || ExitFatal "grep binary not found"
+ [ "${HEADBINARY:-}" ] || ExitFatal "head binary not found"
+ [ "${LSBINARY:-}" ] || ExitFatal "ls binary not found"
+ [ "${PSBINARY:-}" ] || ExitFatal "ps binary not found"
+ [ "${SEDBINARY:-}" ] || ExitFatal "sed binary not found"
+ [ "${SORTBINARY:-}" ] || ExitFatal "sort binary not found"
+ [ "${TRBINARY:-}" ] || ExitFatal "tr binary not found"
+ [ "${UNIQBINARY:-}" ] || ExitFatal "uniq binary not found"
+ [ "${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
+
#
#================================================================================
# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
diff --git a/include/consts b/include/consts
index 671ed1ca..207cde8c 100644
--- a/include/consts
+++ b/include/consts
@@ -46,6 +46,7 @@ unset LANG
#
# == Variable initializing ==
#
+ APTBINARY=""
ARCH_AUDIT_BINARY=""
AUDITORNAME=""
AUDITCTLBINARY=""
@@ -70,6 +71,7 @@ unset LANG
CHKCONFIGBINARY=""
CLAMCONF_BINARY=""
CLAMSCANBINARY=""
+ CLANGBINARY=""
COLORS=1
COMPLIANCE_ENABLE_CIS=0
COMPLIANCE_ENABLE_HIPAA=0
@@ -99,8 +101,11 @@ unset LANG
DNFBINARY=""
DOCKERBINARY=""
DOCKER_DAEMON_RUNNING=0
+ DPKGBINARY=""
ECHOCMD=""
ERROR_ON_WARNINGS=0
+ EQUERYBINARY=""
+ EXIMBINARY=""
FAIL2BANBINARY=""
FILEBINARY=""
FILEVALUE=""
@@ -248,8 +253,10 @@ unset LANG
SHOW_REPORT_SOLUTION=1
SHOW_TOOL_TIPS=1 # Show inline tool tips (default true)
SHOW_WARNINGS_ONLY=0
+ SKIP_GETHOSTID=0
SKIP_PLUGINS=0
SKIP_TESTS=""
+ SKIP_VM_DETECTION=0
SKIPREASON=""
SKIPPED_TESTS_ROOTONLY=""
SMTPCTLBINARY=""
@@ -270,6 +277,7 @@ unset LANG
TESTS_EXECUTED=""
TESTS_SKIPPED=""
TMPFILE=""
+ TOMOYOINITBINARY=""
TOOLTIP_SHOWED=0
TOTAL_SUGGESTIONS=0
TOTAL_WARNINGS=0
diff --git a/include/functions b/include/functions
index 95083600..a0246d68 100644
--- a/include/functions
+++ b/include/functions
@@ -86,6 +86,7 @@
# ReportSuggestion Add a suggestion to report file
# ReportWarning Add a warning and priority to report file
# SafePerms Check if a file has safe permissions
+# SafeInput Test provided string to see if it contains unwanted characters
# SearchItem Search a string in a file
# ShowComplianceFinding Display a particular finding regarding compliance or a security standard
# ShowSymlinkPath Show a path behind a symlink
@@ -659,9 +660,9 @@
RemoveTempFiles
LogText "${PROGRAM_NAME} ended with exit code 1."
if [ $# -eq 1 ]; then
- ${ECHOCMD} ""
- ${ECHOCMD} "${RED}Fatal error${NORMAL}: ${WHITE}$1${NORMAL}"
- ${ECHOCMD} ""
+ ${ECHOCMD:-echo} ""
+ ${ECHOCMD:-echo} "${RED}Fatal error${NORMAL}: ${WHITE}$1${NORMAL}"
+ ${ECHOCMD:-echo} ""
fi
exit 1
}
@@ -805,15 +806,26 @@
# Name : GetHostID()
# Description : Create an unique id for the system
#
- # Returns : optional value
+ # Returns : 0 = fetched or created IDs, 1 = failed, 2 = skipped
# Usage : GetHostID
################################################################################
GetHostID() {
+ if [ ${SKIP_GETHOSTID} -eq 1 ]; then
+ return 2
+ fi
+
if [ ! -z "${HOSTID}" -a ! -z "${HOSTID2}" ]; then
Debug "Skipping creation of host identifiers, as they are already configured (via profile)"
- return 1
+ return 2
+ fi
+
+ if [ -f "${ROOTDIR}etc/lynis/hostids" ]; then
+ Debug "Used hostids file to fetch values"
+ HOSTID=$(grep "^hostid=" ${ROOTDIR}etc/lynis/hostids | awk -F= '{print $2}')
+ HOSTID2=$(grep "^hostid2=" ${ROOTDIR}etc/lynis/hostids | awk -F= '{print $2}')
+ return 0
fi
FIND=""
@@ -1110,8 +1122,9 @@
fi
# Show an exception if no HostID could be created, to ensure each system (and scan) has one
- if [ "${HOSTID}" = "" ]; then
+ if [ -z "${HOSTID}" ]; then
ReportException "GetHostID" "No unique host identifier could be created."
+ return 1
elif [ ! -z "${HOSTID2}" ]; then
return 0
fi
@@ -1284,7 +1297,8 @@
if [ -z "${search}" ]; then ExitFatal "Missing process to search for when using IsRunning function"; fi
RUNNING=0
- if [ ! -z "${PGREPBINARY}" ]; then
+ # AIX does not fully support pgrep options, so using ps instead
+ if [ ! -z "${PGREPBINARY}" -a ! "${OS}" = "AIX" ]; then
FIND=$(${PGREPBINARY} ${pgrep_options} "${search}" | ${TRBINARY} '\n' ' ')
else
if [ -z "${PSOPTIONS}" ]; then
@@ -1392,6 +1406,10 @@
ISVIRTUALMACHINE=2; VMTYPE="unknown"; VMFULLTYPE="Unknown"
SHORT=""
+ if [ ${SKIP_VM_DETECTION} -eq 1 ]; then
+ return 2
+ fi
+
# lxc environ detection
if [ -z "${SHORT}" ]; then
if [ -f /proc/1/environ ]; then
@@ -1699,7 +1717,7 @@
################################################################################
# Name : PackageIsInstalled()
- # Description : Add a separator to log file between sections, tests etc
+ # Description : Determines if a package is installed
# Returns : exit code
# Notes : this function is not used yet, but created in advance to allow
# the addition of support for all operating systems
@@ -1714,11 +1732,20 @@
Fatal "Incorrect usage of PackageIsInstalled function"
fi
- if [ ! -z "${RPMBINARY}" ]; then
- output=$(${RPMBINARY} --quiet -q ${package} 2> /dev/null)
+ if [ ! -z "${DNFBINARY}" ]; then
+ output=$(${DNFBINARY} --quiet --cacheonly --noplugins --assumeno info --installed ${package} > /dev/null 2>&1)
exit_code=$?
- elif ! -z "${DPKGBINARY}" ]; then
- output=$(${DPKGBINARY} -l ${package} 2> /dev/null)
+ elif [ ! -z "${DPKGBINARY}" ]; then
+ output=$(${DPKGBINARY} -l ${package} 2> /dev/null | ${GREPBINARY} "^ii")
+ exit_code=$?
+ elif [ ! -z "${EQUERYBINARY}" ]; then
+ output=$(${EQUERYBINARY} --quiet ${package} > /dev/null 2>&1)
+ exit_code=$? # 0=package installed, 3=package not installed
+ elif [ ! -z "${PKG_BINARY}" ]; then
+ output=$(${PKG_BINARY} -N info ${package} >/dev/null 2>&1)
+ exit_code=$? # 0=package installed, 70=invalid package
+ elif [ ! -z "${RPMBINARY}" ]; then
+ output=$(${RPMBINARY} --quiet -q ${package} > /dev/null 2>&1)
exit_code=$?
elif [ ! -z "${ZYPPERBINARY}" ]; then
output=$(${ZYPPERBINARY} --quiet --non-interactive search --installed -i ${PACKAGE} 2> /dev/null | grep "^i")
@@ -1983,7 +2010,7 @@
for ITEM in ${VALUE}; do
LogText "Result: found protocol ${ITEM}"
case ${ITEM} in
- "sslv2" | "sslv3")
+ "sslv2" | "sslv3" | "tlsv1")
NGINX_WEAK_SSL_PROTOCOL_FOUND=1
;;
esac
@@ -2485,75 +2512,128 @@
################################################################################
+ # Name : SafeInput()
+ # Description : Test provided string to see if it contains unwanted characters
+ #
+ # Input : string + optional class (parameter 2)
+ # Returns : 0 (input considered to be safe) or 1 (validation failed)
+ ################################################################################
+
+ SafeInput() {
+ exitcode=1
+ # By default remove only control characters
+ if [ $# -eq 1 ]; then
+ input="$1"
+ cleaned=$(echo ${input} | tr -d '[:cntrl:]')
+ # If know what to test against, then see if input matches the specified class
+ elif [ $# -eq 2 ]; then
+ input="$1"
+ testchars="$2"
+ cleaned=$(echo $1 | tr -cd "${testchars}")
+ else
+ ExitFatal "No argument or too many arguments provided to SafeInput()"
+ fi
+
+ if [ "${cleaned}" = "${input}" ]; then
+ exitcode=0
+ fi
+ return ${exitcode}
+ }
+
+
+
+ ################################################################################
# Name : SafePerms()
- # Return : 0 (file OK) or break
+ # Description :
+ # Returns : 0 (file permissions OK) or break
################################################################################
SafePerms() {
- if [ ${WARN_ON_FILE_ISSUES} -eq 1 ]; then
+ exitcode=1
+ IS_PARAMETERS=0
+ IS_PROFILE=0
+
+ if [ ${IGNORE_FILE_PERMISSION_ISSUES} -eq 0 ]; then
PERMS_OK=0
LogText "Checking permissions of $1"
- if [ $# -eq 1 ]; then
- IS_PARAMETERS_FILE=$(echo $1 | grep "/parameters")
+
+ if [ $# -gt 0 ]; then
+
+ if [ $# -eq 2 ]; then
+ case "$2" in
+ "parameters")
+ IS_PARAMETERS=1
+ ;;
+ "profile")
+ IS_PROFILE=1
+ ;;
+ esac
+ else
+ FIND=$(echo $1 | grep "/parameters")
+ if [ $? -eq 0 ]; then IS_PARAMETERS=1; fi
+ 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
- else
- PERMS=$(ls -l $1)
- # Owner permissions
- OWNER=$(echo ${PERMS} | awk -F" " '{ print $3 }')
- OWNERID=$(ls -n $1 | awk -F" " '{ print $3 }')
- if [ ${PENTESTINGMODE} -eq 0 -a "${IS_PARAMETERS_FILE}" = "" ]; then
- if [ ! "${OWNER}" = "root" -a ! "${OWNERID}" = "0" ]; then
- echo "Fatal error: file $1 should be owned by user 'root' when running it as root (found: ${OWNER})."
- ExitFatal
- fi
- fi
- # Group permissions
- GROUP=$(echo ${PERMS} | awk -F" " '{ print $4 }')
- GROUPID=$(ls -n $1 | awk -F" " '{ print $4 }')
-
- if [ ${PENTESTINGMODE} -eq 0 -a "${IS_PARAMETERS_FILE}" = "" ]; then
- if [ ! "${GROUP}" = "root" -a ! "${GROUP}" = "wheel" -a ! "${GROUPID}" = "0" ]; then
- echo "Fatal error: group owner of directory $1 should be owned by root user, wheel or similar (found: ${GROUP})."
- ExitFatal
- fi
- fi
-
- # 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"
- ExitFatal
- fi
-
- # Owner permissions
- 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"
- 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"
- ExitFatal
- fi
- # Set PERMS_OK to 1 if no fatal errors occurred
- PERMS_OK=1
- LogText "File permissions are OK"
- return 0
- fi
+ if [ ! -f "$1" ]; then
+ LogText "Fatal error: file $1 does not exist. Quitting."
+ echo "Fatal error: file $1 does not exist"
+ ExitFatal
+ else
+ PERMS=$(ls -l $1)
+
+ # Owner permissions
+ OWNER=$(echo ${PERMS} | awk -F" " '{ print $3 }')
+ OWNERID=$(ls -n $1 | awk -F" " '{ print $3 }')
+ if [ ${PENTESTINGMODE} -eq 0 -a ${IS_PARAMETERS} -eq 0 ]; then
+ if [ ! "${OWNER}" = "root" -a ! "${OWNERID}" = "0" ]; then
+ echo "Fatal error: file $1 should be owned by user 'root' when running it as root (found: ${OWNER})."
+ ExitFatal
+ fi
+ fi
+ # Group permissions
+ GROUP=$(echo ${PERMS} | awk -F" " '{ print $4 }')
+ GROUPID=$(ls -n $1 | awk -F" " '{ print $4 }')
+
+ if [ ${PENTESTINGMODE} -eq 0 -a ${IS_PARAMETERS} -eq 0 ]; then
+ if [ ! "${GROUP}" = "root" -a ! "${GROUP}" = "wheel" -a ! "${GROUPID}" = "0" ]; then
+ echo "Fatal error: group owner of directory $1 should be owned by root user, wheel or similar (found: ${GROUP})."
+ ExitFatal
+ fi
+ fi
+
+ # 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"
+ ExitFatal
+ fi
+
+ # Owner permissions
+ 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"
+ 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"
+ ExitFatal
+ fi
+ # Set PERMS_OK to 1 if no fatal errors occurred
+ PERMS_OK=1
+ LogText "File permissions are OK"
+ exitcode=0
+ fi
else
ReportException "SafePerms()" "Invalid number of arguments for function"
fi
else
PERMS_OK=1
- return 0
+ exitcode=0
fi
+ return ${exitcode}
+
}
diff --git a/include/helper_audit_dockerfile b/include/helper_audit_dockerfile
index efe73d28..3d18556f 100644
--- a/include/helper_audit_dockerfile
+++ b/include/helper_audit_dockerfile
@@ -19,25 +19,14 @@
#################################################################################
if [ $# -eq 0 ]; then
- Display --indent 2 --text "${RED}Error: ${WHITE}Provide URL or file${NORMAL}"
+ Display --indent 2 --text "${RED}Error: ${WHITE}Provide a file${NORMAL}"
Display --text " "; Display --text " "
ExitFatal
else
FILE=$(echo $1 | egrep "^http|https")
if HasData "${FILE}"; then
- CreateTempFile
- TMP_FILE="${TEMP_FILE}"
- Display --indent 2 --text "Downloading URL ${FILE} with wget"
- wget -o ${TMP_FILE} ${FILE}
- if [ $? -gt 0 ]; then
- AUDIT_FILE="${TMP_FILE}"
- else
- if [ -f ${TMP_FILE} ]; then
- rm -f ${TMP_FILE}
- fi
- Display --indent 2 --text "${RED}Error: ${WHITE}can not download file${NORMAL}"
- ExitFatal
- fi
+ echo "Provide a file (not a URL)"
+ ExitFatal
else
if [ -f $1 ]; then
AUDIT_FILE="$1"
@@ -70,13 +59,12 @@ fi
IS_ALPINE=$(echo ${IMAGE} | grep -i alpine)
IS_LATEST=$(echo ${TAG} | grep -i latest)
- if [ ! "${IS_DEBIAN}" = "" ]; then IMAGE="debian"; fi
- if [ ! "${IS_FEDORA}" = "" ]; then IMAGE="fedora"; fi
- if [ ! "${IS_UBUNTU}" = "" ]; then IMAGE="ubuntu"; fi
- if [ ! "${IS_ALPINE}" = "" ]; then IMAGE="alpine"; fi
-
- if [ ! "${IS_LATEST}" = "" ]; then
- ReportWarning "dockerfile" "latest TAG used. Specifying the version is better."
+ if [ ! -z "${IS_DEBIAN}" ]; then IMAGE="debian"; fi
+ if [ ! -z "${IS_FEDORA}" ]; then IMAGE="fedora"; fi
+ if [ ! -z "${IS_UBUNTU}" ]; then IMAGE="ubuntu"; fi
+ if [ ! -z "${IS_ALPINE}" ]; then IMAGE="alpine"; fi
+ if [ ! -z "${IS_LATEST}" ]; then
+ ReportWarning "dockerfile" "latest TAG used. Specifying a targeted OS image and version is better for reproducible results."
fi
case ${IMAGE} in
@@ -110,14 +98,14 @@ InsertSection "Basics"
#FIND=$(egrep "^MAINTAINER" ${AUDIT_FILE} | sed 's/ /:space:/g')
FIND=$(egrep -i "*MAINTAINER" ${AUDIT_FILE} | sed 's/=/ /g' | cut -d'"' -f 2)
- if [ "${FIND}" = "" ]; then
+ if [ -z "${FIND}" ]; then
ReportWarning "dockerfile" "No maintainer found. Unclear who created this file."
else
#MAINTAINER=$(echo ${FIND} | sed 's/:space:/ /g' | awk '{ if($1=="MAINTAINER") { print }}')
MAINTAINER=$(echo ${FIND})
Display --indent 2 --text "Maintainer" --result "${MAINTAINER}"
fi
-
+
FIND=$(grep "^ENTRYPOINT" ${AUDIT_FILE} | cut -d' ' -f2 )
if [ "${FIND}" = "" ]; then
ReportWarning "dockerfile" "No ENTRYPOINT defined in Dockerfile."
@@ -127,7 +115,7 @@ InsertSection "Basics"
fi
FIND=$(grep "^CMD" ${AUDIT_FILE} | cut -d' ' -f2 )
- if [ "${FIND}" = "" ]; then
+ if [ -z "${FIND}" ]; then
ReportWarning "dockerfile" "No CMD defines in Dockerfile."
else
CMD=$(echo ${FIND})
@@ -135,7 +123,7 @@ InsertSection "Basics"
fi
FIND=$(grep "^USER" ${AUDIT_FILE} | cut -d' ' -f2 )
- if [ "${FIND}" = "" ]; then
+ if [ -z "${FIND}" ]; then
ReportWarning "dockerfile" "No user declared in Dockerfile. Container will execute command as root"
else
USER=$(echo ${FIND})
diff --git a/include/helper_generate b/include/helper_generate
new file mode 100644
index 00000000..bdcfb44d
--- /dev/null
+++ b/include/helper_generate
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+#################################################################################
+#
+# Lynis
+# ------------------
+#
+# Copyright 2007-2013, Michael Boelen
+# Copyright 2007-2019, 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.
+#
+######################################################################
+#
+# Helper program to generate specific details such as host IDs
+#
+######################################################################
+#
+# How to use:
+# ------------
+# Run: lynis generate <option>
+#
+######################################################################
+
+SAVEFILE=0
+GENERATE_ARGS="hostids"
+
+if [ $# -gt 0 ]; then
+ case $1 in
+ "hostids")
+
+ if [ $# -gt 1 ]; then
+ shift
+ if [ $1 = "--save" ]; then
+ SAVEFILE=1
+ fi
+ fi
+
+ # Generate random host IDs
+ HOSTID=$(head -c20 < /dev/urandom | xxd -c 20 -p)
+ HOSTID2=$(head -c32 < /dev/urandom | xxd -c 32 -p)
+
+ ${ECHOCMD} "Generated host identifiers"
+ ${ECHOCMD} "- hostid: ${HOSTID}"
+ ${ECHOCMD} "- hostid2: ${HOSTID2}"
+
+ if [ ${SAVEFILE} -eq 1 ]; then
+ FILE="${ROOTDIR}etc/lynis/hostids"
+ if [ -f ${FILE} ]; then
+ ${ECHOCMD} "Error: hostids file already exists (${FILE})"
+ ${ECHOCMD} "Remove the file first and rerun command"
+ ExitFatal
+ else
+ OUTPUT=$(touch ${FILE} 2> /dev/null)
+ if [ $? -eq 0 ]; then
+ ${ECHOCMD} "Created hostids file (${FILE})"
+ echo "# generated using 'lynis generate hostids --save'" > ${FILE}
+ echo "hostid=${HOSTID}" >> ${FILE}
+ echo "hostid2=${HOSTID2}" >> ${FILE}
+ else
+ ExitFatal "Error: could not created hostids file (${FILE}). Issue with permissions?"
+ fi
+ fi
+ fi
+
+ ExitClean
+ ;;
+ *) ${ECHOCMD} "Unknown argument '${RED}$1${NORMAL}' for lynis generate" ;;
+ esac
+else
+ ${ECHOCMD} "\n ${WHITE}Provide an additional argument${NORMAL}\n\n"
+ for ITEM in ${GENERATE_ARGS}; do
+ ${ECHOCMD} " lynis generate ${BROWN}${ITEM}${NORMAL}"
+ done
+ ${ECHOCMD} "\n"
+ ${ECHOCMD} ""
+ ${ECHOCMD} "Extended help about the generate command can be provided with: $0 show commands generate"
+fi
+
+
+ExitClean
+
+# The End
diff --git a/include/helper_show b/include/helper_show
index 6e0738e6..874b3e1b 100644
--- a/include/helper_show
+++ b/include/helper_show
@@ -28,7 +28,7 @@
#
######################################################################
-COMMANDS="audit configure show update upload-only"
+COMMANDS="audit configure generate show update upload-only"
HELPERS="audit configure show update"
OPTIONS="--auditor\n--cronjob (--cron)\n--debug\n--developer\n--help (-h)\n--license-key\n--log-file\n--manpage (--man)\n--no-colors\n--no-log\n--pentest\n--profile\n--plugin-dir\n--quick (-Q)\n--quiet (-q)\n--report-file\n--reverse-colors\n--skip-plugins\n--tests\n--tests-from-category\n--tests-from-group\n--upload\n--verbose\n--version (-V)\n--wait\n--warnings-only"
@@ -94,6 +94,17 @@ AUDIT_HELP="
"
+GENERATE_ARGS="( --save )"
+GENERATE_HELP="
+ Generate random value for hostid and hostid2
+ ${WHITE}lynis generate hostids${NORMAL}
+
+ Generate and save values
+ ${WHITE}lynis generate hostids --save${NORMAL}
+
+"
+
+
UPDATE_ARGS="check info"
UPDATE_HELP="
${CYAN}update info${NORMAL}
@@ -274,6 +285,7 @@ if [ $# -gt 0 ]; then
shift
case $1 in
"audit") ${ECHOCMD} "${AUDIT_HELP}" ;;
+ "generate") ${ECHOCMD} "${GENERATE_HELP}" ;;
"show") ${ECHOCMD} "${SHOW_HELP}" ;;
"update") ${ECHOCMD} "${UPDATE_HELP}" ;;
"upload-only") ${ECHOCMD} "${UPLOAD_ONLY_HELP}" ;;
diff --git a/include/osdetection b/include/osdetection
index 5ab80293..a6c18bb5 100644
--- a/include/osdetection
+++ b/include/osdetection
@@ -477,7 +477,7 @@
ECHONB=""
case ${OS} in
- "AIX") ECHOCMD="echo" ;;
+ "AIX") ECHOCMD="echo"; ECHONB="printf" ;;
"DragonFly"|"FreeBSD"|"NetBSD") ECHOCMD="echo -e"; ECHONB="echo -n" ;;
"macOS" | "Mac OS X") ECHOCMD="echo"; ECHONB="/bin/echo -n" ;;
"Solaris") ECHOCMD="echo" ; test -f /usr/ucb/echo && ECHONB="/usr/ucb/echo -n" ;;
diff --git a/include/parameters b/include/parameters
index 96d63524..0798224e 100644
--- a/include/parameters
+++ b/include/parameters
@@ -22,8 +22,21 @@
#
#################################################################################
#
- # Check number of parameters submitted (at least one is needed)
PARAMCOUNT=$#
+
+
+ # Input validation on provided parameters and their arguments
+ COUNT=0
+ for I in "$@"; do
+ COUNT=$((COUNT + 1))
+ if ! SafeInput "${I}"; then
+ echo "Execution of ${PROGRAM_NAME} stopped as we found unexpected input or invalid characters in argument ${COUNT}"
+ echo "Do you believe this is in error? Let us know: ${PROGRAM_AUTHOR_CONTACT}"
+ ExitFatal "Program execution stopped due to security measure"
+ fi
+ done
+
+ # Parse arguments
while [ $# -ge 1 ]; do
case $1 in
# Helpers first
@@ -36,12 +49,13 @@
if [ $# -gt 1 ]; then
case $2 in
"dockerfile")
- if [ "$3" = "" ]; then
+ if [ $# = 2 ]; then
echo "${RED}Error: ${WHITE}Missing file name or URL${NORMAL}"
- echo "Example: $0 audit dockerfile /root/Dockerfile"
+ echo "Example: $0 audit dockerfile /path/to/Dockerfile"
ExitFatal
else
shift; shift
+ CHECK_BINARIES=1
HELPER_PARAMS="$1"
HELPER="audit_dockerfile"
break
@@ -111,6 +125,24 @@
break
;;
+ # Generate data
+ generate)
+ CHECK_BINARIES=0
+ HELPER="generate"
+ LOGTEXT=0
+ QUIET=1
+ RUN_HELPERS=1
+ RUN_TESTS=0
+ RUN_UPDATE_CHECK=0
+ SKIP_GETHOSTID=1
+ SKIP_PLUGINS=1
+ SKIP_VM_DETECTION=1
+ SHOW_PROGRAM_DETAILS=0
+ SHOW_TOOL_TIPS=0
+ shift; HELPER_PARAMS="$@"
+ break
+ ;;
+
# Show Lynis details
show)
CHECK_BINARIES=0
diff --git a/include/report b/include/report
index b200f6be..2df666e4 100644
--- a/include/report
+++ b/include/report
@@ -22,55 +22,79 @@
#
#################################################################################
#
+
+ # Add data fields to report file
+ Report "dhcp_client_running=${DHCP_CLIENT_RUNNING}"
+ Report "arpwatch_running=${ARPWATCH_RUNNING}"
+
+ # Report firewall installed for now, if we found one active. Next step would be determining binaries first and apply additional checks.
+ Report "firewall_active=${FIREWALL_ACTIVE}"
+ Report "firewall_empty_ruleset=${FIREWALL_EMPTY_RULESET}"
+ Report "firewall_installed=${FIREWALL_ACTIVE}"
+
+ if [ ! -z "${INSTALLED_PACKAGES}" ]; then Report "installed_packages_array=${INSTALLED_PACKAGES}"; fi
+
+ 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
- # Define approximately how strong a machine has been hardened
- # If no hardening has been found, set value to 1
- if [ ${HPPOINTS} -eq 0 ]; then HPPOINTS=1; HPTOTAL=100; fi
- HPINDEX=$((HPPOINTS * 100 / HPTOTAL))
- HPAOBLOCKS=$((HPPOINTS * 20 / HPTOTAL))
- # Set color related to rating
- if [ ${HPINDEX} -lt 50 ]; then
- HPCOLOR="${RED}"
- HIDESCRIPTION="System has not or a low amount been hardened"
- elif [ ${HPINDEX} -gt 49 -a ${HPINDEX} -lt 80 ]; then
- HPCOLOR="${YELLOW}"
- HIDESCRIPTION="System has been hardened, but could use additional hardening"
- elif [ ${HPINDEX} -gt 79 -a ${HPINDEX} -lt 90 ]; then
- HPCOLOR="${GREEN}"
- HIDESCRIPTION="System seem to be decent hardened"
- elif [ ${HPINDEX} -gt 89 ]; then
- HPCOLOR="${GREEN}"
- HIDESCRIPTION="System seem to be well hardened"
- fi
+ # Goal:
+ # Provide a visual way to show how much the system is hardened
+ #
+ # Important:
+ # The index gives a simplified version of the measures taken on the system.
+ # It should be used to get a first impression about the state of the system or to compare similar systems.
+ # Getting the maximum score (100 or full bar) does not indicate that the system is fully secured.
+
+ # If no hardening has been found, set value to 1
+ if [ ${HPPOINTS} -eq 0 ]; then HPPOINTS=1; HPTOTAL=100; fi
+ HPINDEX=$((HPPOINTS * 100 / HPTOTAL))
+ HPAOBLOCKS=$((HPPOINTS * 20 / HPTOTAL))
+ # Set color related to rating
+ if [ ${HPINDEX} -lt 50 ]; then
+ HPCOLOR="${RED}"
+ HIDESCRIPTION="System has not or a low amount been hardened"
+ elif [ ${HPINDEX} -gt 49 -a ${HPINDEX} -lt 80 ]; then
+ HPCOLOR="${YELLOW}"
+ HIDESCRIPTION="System has been hardened, but could use additional hardening"
+ elif [ ${HPINDEX} -gt 79 -a ${HPINDEX} -lt 90 ]; then
+ HPCOLOR="${GREEN}"
+ HIDESCRIPTION="System seem to be decent hardened"
+ elif [ ${HPINDEX} -gt 89 ]; then
+ HPCOLOR="${GREEN}"
+ HIDESCRIPTION="System seem to be well hardened"
+ fi
- case ${HPAOBLOCKS} in
- 0) HPBLOCKS="#"; HPEMPTY=" " ;;
- 1) HPBLOCKS="#"; HPEMPTY=" " ;;
- 2) HPBLOCKS="##"; HPEMPTY=" " ;;
- 3) HPBLOCKS="###"; HPEMPTY=" " ;;
- 4) HPBLOCKS="####"; HPEMPTY=" " ;;
- 5) HPBLOCKS="#####"; HPEMPTY=" " ;;
- 6) HPBLOCKS="######"; HPEMPTY=" " ;;
- 7) HPBLOCKS="#######"; HPEMPTY=" " ;;
- 8) HPBLOCKS="########"; HPEMPTY=" " ;;
- 9) HPBLOCKS="#########"; HPEMPTY=" " ;;
- 10) HPBLOCKS="##########"; HPEMPTY=" " ;;
- 11) HPBLOCKS="###########"; HPEMPTY=" " ;;
- 12) HPBLOCKS="############"; HPEMPTY=" " ;;
- 13) HPBLOCKS="#############"; HPEMPTY=" " ;;
- 14) HPBLOCKS="##############"; HPEMPTY=" " ;;
- 15) HPBLOCKS="###############"; HPEMPTY=" " ;;
- 16) HPBLOCKS="################"; HPEMPTY=" " ;;
- 17) HPBLOCKS="#################"; HPEMPTY=" " ;;
- 18) HPBLOCKS="##################"; HPEMPTY=" " ;;
- 19) HPBLOCKS="###################"; HPEMPTY=" " ;;
- 20) HPBLOCKS="####################"; HPEMPTY="" ;;
- esac
+ case ${HPAOBLOCKS} in
+ 0) HPBLOCKS="#"; HPEMPTY=" " ;;
+ 1) HPBLOCKS="#"; HPEMPTY=" " ;;
+ 2) HPBLOCKS="##"; HPEMPTY=" " ;;
+ 3) HPBLOCKS="###"; HPEMPTY=" " ;;
+ 4) HPBLOCKS="####"; HPEMPTY=" " ;;
+ 5) HPBLOCKS="#####"; HPEMPTY=" " ;;
+ 6) HPBLOCKS="######"; HPEMPTY=" " ;;
+ 7) HPBLOCKS="#######"; HPEMPTY=" " ;;
+ 8) HPBLOCKS="########"; HPEMPTY=" " ;;
+ 9) HPBLOCKS="#########"; HPEMPTY=" " ;;
+ 10) HPBLOCKS="##########"; HPEMPTY=" " ;;
+ 11) HPBLOCKS="###########"; HPEMPTY=" " ;;
+ 12) HPBLOCKS="############"; HPEMPTY=" " ;;
+ 13) HPBLOCKS="#############"; HPEMPTY=" " ;;
+ 14) HPBLOCKS="##############"; HPEMPTY=" " ;;
+ 15) HPBLOCKS="###############"; HPEMPTY=" " ;;
+ 16) HPBLOCKS="################"; HPEMPTY=" " ;;
+ 17) HPBLOCKS="#################"; HPEMPTY=" " ;;
+ 18) HPBLOCKS="##################"; HPEMPTY=" " ;;
+ 19) HPBLOCKS="###################"; HPEMPTY=" " ;;
+ 20) HPBLOCKS="####################"; HPEMPTY="" ;;
+ esac
- HPGRAPH="[${HPCOLOR}${HPBLOCKS}${NORMAL}${HPEMPTY}]"
- LogText "Hardening index : [${HPINDEX}] [${HPBLOCKS}${HPEMPTY}]"
- LogText "Hardening strength: ${HIDESCRIPTION}"
+ HPGRAPH="[${HPCOLOR}${HPBLOCKS}${NORMAL}${HPEMPTY}]"
+ LogText "Hardening index : [${HPINDEX}] [${HPBLOCKS}${HPEMPTY}]"
+ LogText "Hardening strength: ${HIDESCRIPTION}"
# Only show overview if not running in quiet mode
diff --git a/include/tests_authentication b/include/tests_authentication
index fe8ece41..6c867da6 100644
--- a/include/tests_authentication
+++ b/include/tests_authentication
@@ -40,7 +40,12 @@
if [ ${SKIPTEST} -eq 0 ]; then
# Search accounts with UID 0
LogText "Test: Searching accounts with UID 0"
- FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${EGREPBINARY} -v '^#|^root:|^(\+:\*)?:0:0:::' | ${CUTBINARY} -d ":" -f1,3 | ${GREPBINARY} ':0')
+ # Check if device is a QNAP, as the root user is called admin, and not root
+ if [ ${QNAP_DEVICE} -eq 1 ]; then
+ FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${EGREPBINARY} -v '^#|^admin:|^(\+:\*)?:0:0:::' | ${CUTBINARY} -d ":" -f1,3 | ${GREPBINARY} ':0')
+ else
+ FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${EGREPBINARY} -v '^#|^root:|^(\+:\*)?:0:0:::' | ${CUTBINARY} -d ":" -f1,3 | ${GREPBINARY} ':0')
+ fi
if [ ! -z "${FIND}" ]; then
Display --indent 2 --text "- Administrator accounts" --result "${STATUS_WARNING}" --color RED
LogText "Result: Found more than one administrator accounts"
@@ -669,8 +674,8 @@
if [ -d ${DIR} -a ! -L ${DIR} ]; then
LogText "Result: directory ${DIR} exists"
# Search in the specified directory
- if [ "${OS}" = "Solaris" ]; then
- # Solaris does not support -maxdepth
+ if [ "${OS}" = "AIX" -o "${OS}" = "Solaris" ]; then
+ # AIX/Solaris does not support -maxdepth
FIND=$(find ${DIR} -type f -name "pam_*.so" -print | sort)
else
FIND=$(find ${DIR} -maxdepth 1 -type f -name "pam_*.so" -print | sort)
@@ -698,25 +703,32 @@
#
# Test : AUTH-9278
# Description : Search LDAP support in PAM files
- Register --test-no AUTH-9278 --weight L --network NO --category security --description "Checking LDAP pam status"
+ Register --test-no AUTH-9278 --weight L --network NO --category security --description "Determine LDAP support in PAM files"
if [ ${SKIPTEST} -eq 0 ]; then
- LogText "Test: checking presence /etc/pam.d/common-auth"
- if [ -f /etc/pam.d/common-auth ]; then
- LogText "Result: file /etc/pam.d/common-auth exists"
- LogText "Test: checking presence LDAP module"
- FIND=$(${GREPBINARY} "^auth.*ldap" /etc/pam.d/common-auth)
- if [ ! "${FIND}" = "" ]; then
- LogText "Result: LDAP module present"
- LogText "Output: ${FIND}"
- Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_FOUND}" --color GREEN
- LDAP_AUTH_ENABLED=1
- LDAP_PAM_ENABLED=1
+ AUTH_FILES="${ROOTDIR}etc/pam.d/common-auth ${ROOTDIR}etc/pam.d/system-auth"
+ for FILE in ${AUTH_FILES}; do
+ LogText "Test: checking presence ${FILE}"
+ if [ -f ${FILE} ]; then
+ LogText "Result: file ${FILE} exists"
+ LogText "Test: checking presence LDAP module"
+ FIND=$(${GREPBINARY} "^auth.*ldap" ${FILE})
+ if [ ! -z "${FIND}" ]; then
+ LogText "Result: LDAP module present"
+ LogText "Output: ${FIND}"
+ LDAP_AUTH_ENABLED=1
+ LDAP_PAM_ENABLED=1
+ else
+ LogText "Result: LDAP module not found"
+ fi
else
- LogText "Result: LDAP module not found"
- Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_NOT_FOUND}" --color WHITE
+ LogText "Result: file ${FILE} not found, skipping test"
fi
+ done
+
+ if [ ${LDAP_PAM_ENABLED} -eq 1 ]; then
+ Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_FOUND}" --color GREEN
else
- LogText "Result: file /etc/pam.d/common-auth not found, skipping test"
+ Display --indent 2 --text "- LDAP module in PAM" --result "${STATUS_NOT_FOUND}" --color WHITE
fi
fi
#
diff --git a/include/tests_boot_services b/include/tests_boot_services
index 5495938c..42b8dab1 100644
--- a/include/tests_boot_services
+++ b/include/tests_boot_services
@@ -96,7 +96,11 @@
;;
"init" | "initsplash")
- SERVICE_MANAGER="SysV Init"
+ if [ -d ${ROOTDIR}etc/rc.d ]; then
+ SERVICE_MANAGER="bsdrc.d"
+ else
+ SERVICE_MANAGER="SysV Init"
+ fi
;;
systemd)
SERVICE_MANAGER="systemd"
diff --git a/include/tests_filesystems b/include/tests_filesystems
index a52bb66b..4e52ea5e 100644
--- a/include/tests_filesystems
+++ b/include/tests_filesystems
@@ -48,7 +48,11 @@
Display --indent 4 --text "- Checking ${I} mount point" --result SYMLINK --color WHITE
elif [ -d ${I} ]; then
LogText "Result: directory ${I} exists"
- FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($3==MP) { print $3 }}')
+ case "${OS}" in
+ "AIX") FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($2==MP) { print $2 }}') ;;
+ *) FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($3==MP) { print $3 }}') ;;
+ esac
+
if IsEmpty "${FIND}"; then
LogText "Result: ${I} not found in mount list. Directory most likely stored on / file system"
Display --indent 4 --text "- Checking ${I} mount point" --result "${STATUS_SUGGESTION}" --color YELLOW
@@ -158,7 +162,27 @@
done
else
LogText "Result: no EXT file systems found"
- Report "file_systems_ext[]=none"
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : FILE-6324
+ # Description : Checking Linux XFS file systems
+ Register --test-no FILE-6324 --os Linux --weight L --network NO --category security --description "Checking XFS file systems"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ LogText "Test: Checking for Linux XFS file systems"
+ FIND=$(${MOUNTBINARY} -t xfs | ${AWKBINARY} '{ print $3","$5 }')
+ if [ ! -z "${FIND}" ]; then
+ LogText "Result: found one or more XFS file systems"
+ for I in ${FIND}; do
+ FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d ',' -f1)
+ FILETYPE=$(echo ${I} | ${CUTBINARY} -d ',' -f2)
+ LogText "File system: ${FILESYSTEM} (type: ${FILETYPE})"
+ Report "file_systems_xfs[]=${FILESYSTEM}|${FILETYPE}|"
+ done
+ else
+ LogText "Result: no XFS file systems found"
fi
fi
#
@@ -540,13 +564,13 @@
# ---------------------------------------------------------
FILESYSTEMS_TO_CHECK="/boot:nodev,noexec,nosuid /dev/shm:nosuid,nodev,noexec /home:nodev,nosuid /tmp:nodev,noexec,nosuid /var:nosuid /var/log:nodev,noexec,nosuid /var/log/audit:nodev,noexec,nosuid /var/tmp:nodev,noexec,nosuid"
- Register --test-no FILE-6374 --os Linux --weight L --network NO --category security --description "Checking /boot mount options"
+ Register --test-no FILE-6374 --os Linux --weight L --network NO --category security --description "Checking partitions mount options"
if [ ${SKIPTEST} -eq 0 ]; then
if [ -f /etc/fstab ]; then
for I in ${FILESYSTEMS_TO_CHECK}; do
FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d: -f1)
EXPECTED_FLAGS=$(echo ${I} | ${CUTBINARY} -d: -f2 | ${SEDBINARY} 's/,/ /g')
- FS_FSTAB=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $3 } }' /etc/fstab)
+ FS_FSTAB=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $3 } }' ${ROOTDIR}etc/fstab)
if [ "${FS_FSTAB}" = "glusterfs" ]; then
EXPECTED_FLAGS=$(echo ${EXPECTED_FLAGS} | ${SEDBINARY} 's/\<\(nodev\|nosuid\)\> *//g')
if [ -z "${EXPECTED_FLAGS}" ]; then
@@ -554,7 +578,7 @@
fi
fi
if [ ! -z "${FS_FSTAB}" ]; then
- FOUND_FLAGS=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $4 } }' /etc/fstab | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\n' ' ')
+ FOUND_FLAGS=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $4 } }' ${ROOTDIR}etc/fstab | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\n' ' ')
LogText "File system: ${FILESYSTEM}"
LogText "Expected flags: ${EXPECTED_FLAGS}"
LogText "Found flags: ${FOUND_FLAGS}"
@@ -562,7 +586,7 @@
FULLY_HARDENED=1
for FLAG in ${EXPECTED_FLAGS}; do
FLAG_AVAILABLE=$(echo ${FOUND_FLAGS} | ${GREPBINARY} ${FLAG})
- if [ "${FLAG_AVAILABLE}" = "" ]; then
+ if [ -z "${FLAG_AVAILABLE}" ]; then
LogText "Result: Could not find mount option ${FLAG} on file system ${FILESYSTEM}"
FULLY_HARDENED=0
else
diff --git a/include/tests_firewalls b/include/tests_firewalls
index 85f2b150..735059fe 100644
--- a/include/tests_firewalls
+++ b/include/tests_firewalls
@@ -596,11 +596,6 @@
#################################################################################
#
-# Report firewall installed for now, if we found one active. Next step would be determining binaries first and apply additional checks.
-Report "firewall_active=${FIREWALL_ACTIVE}"
-Report "firewall_empty_ruleset=${FIREWALL_EMPTY_RULESET}"
-Report "firewall_installed=${FIREWALL_ACTIVE}"
-
WaitForKeyPress
#
diff --git a/include/tests_insecure_services b/include/tests_insecure_services
index 277791d9..841189d8 100644
--- a/include/tests_insecure_services
+++ b/include/tests_insecure_services
@@ -18,7 +18,7 @@
#
#################################################################################
#
-# Unsecure services
+# Insecure services
#
#################################################################################
#
@@ -28,32 +28,55 @@
#
INETD_ACTIVE=0
INETD_CONFIG_FILE="${ROOTDIR}etc/inetd.conf"
+ INETD_PACKAGE_INSTALLED=0
+ XINETD_ACTIVE=0
+ XINETD_CONFIG_FILE="${ROOTDIR}etc/xinetd.conf"
+ XINETD_CONFIG_DIR="${ROOTDIR}etc/xinetd.d"
+#
+#################################################################################
+#
+ # Test : INSE-8000
+ # Description : Check for installed inetd package
+ Register --test-no INSE-8000 --weight L --network NO --category security --description "Installed inetd package"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check for installed inetd daemon
+ LogText "Test: Checking if inetd is installed"
+ if PackageIsInstalled "inetd"; then
+ INETD_PACKAGE_INSTALLED=1
+ LogText "Result: inetd is installed"
+ Display --indent 2 --text "- Installed inetd package" --result "${STATUS_FOUND}" --color YELLOW
+ #ReportSuggestion ${TEST_NO} "If there are no inetd services required, it is recommended that the daemon be removed"
+ else
+ LogText "Result: inetd is NOT installed"
+ Display --indent 2 --text "- Installed inetd package" --result "${STATUS_NOT_FOUND}" --color GREEN
+ fi
+ fi
#
#################################################################################
#
# Test : INSE-8002
# Description : Check for inetd status
- Register --test-no INSE-8002 --weight L --network NO --category security --description "Check for enabled inet daemon"
+ if [ ${INETD_PACKAGE_INSTALLED} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no INSE-8002 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check for enabled inet daemon"
if [ ${SKIPTEST} -eq 0 ]; then
# Check running processes
LogText "Test: Searching for active inet daemon"
- IsRunning inetd
- if [ ${RUNNING} -eq 1 ]; then
+ if IsRunning "inetd"; then
LogText "Result: inetd is running"
- Display --indent 2 --text "- Checking inetd status" --result "ACTIVE" --color GREEN
+ Display --indent 4 --text "- inetd status" --result "ACTIVE" --color GREEN
INETD_ACTIVE=1
else
LogText "Result: inetd is NOT running"
- Display --indent 2 --text "- Checking inetd status" --result "NOT ACTIVE" --color GREEN
+ Display --indent 4 --text "- inetd status" --result "NOT ACTIVE" --color GREEN
fi
fi
#
#################################################################################
#
# Test : INSE-8004
- # Description : Check for inetd configuration file
+ # Description : Check for inetd configuration file (inetd)
if [ ${INETD_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
- Register --test-no INSE-8004 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check for enabled inet daemon"
+ Register --test-no INSE-8004 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Presence of inetd configuration file"
if [ ${SKIPTEST} -eq 0 ]; then
# Check configuration file
LogText "Test: Searching for file ${INETD_CONFIG_FILE}"
@@ -73,15 +96,15 @@
if [ ${INETD_ACTIVE} -eq 0 -a -f ${INETD_CONFIG_FILE} ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no INSE-8006 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check configuration of inetd when disabled"
if [ ${SKIPTEST} -eq 0 ]; then
- # Check if any service is enabled in /etc/inetd.conf (inetd is not active, see test 8002)
- LogText "Test: check if all services are disabled if inetd is disabled"
+ # Check if any service is enabled in /etc/inetd.conf (inetd is not active, see test INSE-8002)
+ LogText "Test: check if all services are disabled when inetd is disabled"
FIND=$(${GREPBINARY} -v "^#" ${INETD_CONFIG_FILE} | ${GREPBINARY} -v "^$")
if [ -z "${FIND}" ]; then
LogText "Result: no services found in ${INETD_CONFIG_FILE}"
- Display --indent 4 --text "- Checking inetd.conf services" --result "${STATUS_OK}" --color GREEN
+ Display --indent 4 --text "- Checking enabled inetd services" --result "${STATUS_OK}" --color GREEN
else
LogText "Result: found services in inetd, even though inetd is not running"
- Display --indent 4 --text "- Checking inetd.conf services" --result "${STATUS_SUGGESTION}" --color YELLOW
+ Display --indent 4 --text "- Checking enabled inetd services" --result "${STATUS_SUGGESTION}" --color YELLOW
ReportSuggestion ${TEST_NO} "Although inetd is not running, make sure no services are enabled in ${INETD_CONFIG_FILE}, or remove inetd service"
fi
fi
@@ -95,7 +118,7 @@
if [ ${SKIPTEST} -eq 0 ]; then
LogText "Test: checking telnet presence in inetd configuration"
FIND=$(${GREPBINARY} "^telnet" ${INETD_CONFIG_FILE})
- if [ "${FIND}" = "" ]; then
+ if [ -z "${FIND}" ]; then
LogText "Result: telnet not enabled in ${INETD_CONFIG_FILE}"
Display --indent 2 --text "- Checking inetd (telnet)" --result "${STATUS_NOT_FOUND}" --color GREEN
AddHP 3 3
@@ -109,6 +132,289 @@
#
#################################################################################
#
+ # Test : INSE-8100
+ # Description : Check for installed xinetd daemon
+ Register --test-no INSE-8100 --weight L --network NO --category security --description "Check for installed xinetd daemon"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check for installed xinetd daemon
+ LogText "Test: Checking for installed xinetd daemon"
+ if PackageIsInstalled "xinetd"; then
+ LogText "Result: xinetd is installed"
+ Display --indent 2 --text "- Installed xinetd package" --result "${STATUS_FOUND}" --color YELLOW
+ ReportSuggestion ${TEST_NO} "If there are no xinetd services required, it is recommended that the daemon be removed"
+ else
+ LogText "Result: xinetd is NOT installed"
+ Display --indent 2 --text "- Installed xinetd package" --result "${STATUS_OK}" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8102
+ # Description : Check for xinetd status
+ Register --test-no INSE-8102 --weight L --network NO --category security --description "Check for active xinet daemon"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check running processes
+ LogText "Test: Searching for active extended internet services daemon (xinetd)"
+ if IsRunning "xinetd"; then
+ LogText "Result: xinetd is running"
+ Display --indent 4 --text "- xinetd status" --result "ACTIVE" --color GREEN
+ XINETD_ACTIVE=1
+ else
+ LogText "Result: xinetd is NOT running"
+ Display --indent 4 --text "- xinetd status" --result "NOT ACTIVE" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8104
+ # Description : Check for xinetd configuration file
+ if [ ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no INSE-8104 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check for enabled xinet daemon"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check configuration file
+ LogText "Test: Searching for file ${XINETD_CONFIG_FILE}"
+ if [ -f "${XINETD_CONFIG_FILE}" ]; then
+ LogText "Result: ${XINETD_CONFIG_FILE} exists"
+ Display --indent 6 --text "- Configuration file (xinetd.conf)" --result "${STATUS_FOUND}" --color WHITE
+ else
+ LogText "Result: ${XINETD_CONFIG_FILE} does not exist"
+ Display --indent 6 --text "- Configuration file (xinetd.conf)" --result "${STATUS_NOT_FOUND}" --color WHITE
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8106
+ # Description : Check for xinetd configuration file contents if xinetd is NOT active
+ if [ ${XINETD_ACTIVE} -eq 0 -a -f ${XINETD_CONFIG_FILE} ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no INSE-8106 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check configuration of xinetd when disabled"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check if any service is enabled in /etc/xinetd.d (xinetd is not active, see test INSE-8102)
+ LogText "Test: check if all services are disabled if xinetd is disabled"
+ FIND=$(${GREPBINARY} -r "disable\s*=\s*no" ${XINETD_CONFIG_DIR})
+ if [ -z "${FIND}" ]; then
+ LogText "Result: no services found in ${XINETD_CONFIG_DIR}"
+ Display --indent 6 --text "- Enabled xinetd.d services" --result "${STATUS_NOT_FOUND}" --color GREEN
+ else
+ LogText "Result: found services in ${XINETD_CONFIG_DIR}, even though xinetd is not running"
+ Display --indent 6 --text "- Enabled xinetd.d services" --result "${STATUS_FOUND}" --color YELLOW
+ ReportSuggestion ${TEST_NO} "Although xinetd is not running, make sure no services are enabled in ${XINETD_CONFIG_DIR}, or remove xinetd service"
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8116
+ # Description : Check for insecure services enabled via xinetd
+ if [ ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no INSE-8116 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Insecure services enabled via xinetd"
+ 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"
+
+ for SERVICE in ${ITEMS}; do
+ LogText "Test: checking service ${SERVICE}"
+ if ! SkipAtomicTest "${TEST_NO}:${SERVICE}"; then
+ FILE="${XINETD_CONFIG_DIR}/${SERVICE}"
+ if [ -f "${FILE}" ]; then
+ LogText "Test: checking status in xinetd configuration file (${FILE})"
+ FIND=$(${GREPBINARY} "disable\s*=\s*no" ${FILE})
+ if [ ! -z "${FIND}" ]; then
+ LogText "Result: found insecure service enabled: ${SERVICE}"
+ XINETD_INSECURE_SERVICE_FOUND=1
+ ReportSuggestion "${TEST_NO}" "Disable or remove any insecure services in the xinetd configuration" "${SERVICE}" "text:See log file for more details"
+ Report "insecure_service[]=${SERVICE}"
+ fi
+ fi
+ else
+ LogText "Result: skipped, as this item is excluded using the profile"
+ fi
+ done
+
+ if [ ${XINETD_INSECURE_SERVICE_FOUND} -eq 0 ]; then
+ LogText "Result: no insecure services found in xinetd configuration"
+ Display --indent 6 --text "- Checking xinetd (insecure services)" --result "${STATUS_OK}" --color GREEN
+ AddHP 3 3
+ else
+ LogText "Result: one ore more insecure services discovered in xinetd configuration"
+ Display --indent 6 --text "- Checking xinetd (insecure services)" --result "${STATUS_WARNING}" --color RED
+ AddHP 0 3
+ fi
+ 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
+ if [ ${INETD_ACTIVE} -eq 1 -o ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ Register --test-no INSE-8200 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check if tcp_wrappers is installed when inetd/xinetd is active"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ LogText "Test: Checking if tcp_wrappers is installed"
+ FOUND=0
+ PACKAGES="tcp_wrappers tcpd"
+ for PACKAGE in ${PACKAGES}; do
+ if PackageIsInstalled "${PACKAGE}"; then LogText "Package '${PACKAGE}' is installed"; FOUND=1; fi
+ done
+ if [ ${FOUND} -eq 1 ]; then
+ LogText "Result: tcp_wrappers is installed"
+ Display --indent 2 --text "- Checking tcp_wrappers installation" --result "${STATUS_OK}" --color GREEN
+ else
+ LogText "Result: tcp_wrappers is NOT installed"
+ Display --indent 2 --text "- Checking tcp_wrappers installation" --result "${STATUS_SUGGESTION}" --color YELLOW
+ #ReportSuggestion ${TEST_NO} "When network services are using the inetd/xinetd service, the tcp_wrappers package should be installed"
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8300
+ # Description : Check if rsh client is installed
+ Register --test-no INSE-8300 --weight L --network NO --category security --description "Check if rsh client is installed"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ LogText "Test: Checking if rsh client is installed"
+ FOUND=0
+ PACKAGES="rsh rsh-client rsh-redone-client"
+ for PACKAGE in ${PACKAGES}; do
+ if PackageIsInstalled "${PACKAGE}"; then LogText "Package '${PACKAGE}' is installed"; FOUND=1; fi
+ done
+ if [ ${FOUND} -eq 1 ]; then
+ LogText "Result: rsh client is installed"
+ Display --indent 2 --text "- Installed rsh client package" --result "${STATUS_SUGGESTION}" --color YELLOW
+ ReportSuggestion ${TEST_NO} "Remove rsh client when it is not in use or replace with the more secure SSH package"
+ else
+ LogText "Result: rsh client is NOT installed"
+ Display --indent 2 --text "- Installed rsh client package" --result "${STATUS_OK}" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8302
+ # Description : Check presence of rsh Trust Files
+ #Register --test-no INSE-8302 --weight L --network NO --category security --description "Check presence of rsh Trust Files"
+ #if [ ${SKIPTEST} -eq 0 ]; then
+ # # Check presence of Rsh Trust Files
+ # 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
+ # for RHOSTS in ${DIR}/.rhosts; do
+ # if [ ! -h ${RHOSTS} -a -f ${RHOSTS} ]; then
+ # LogText "FOUND .rhosts file in home directory ${DIR} of ${USER}"
+ # FOUND=1
+ # fi
+ # done
+ # fi
+ # done
+ # if [ -f /etc/hosts.equiv ];then
+ # LogText "FOUND /etc/hosts.equiv"
+ # FOUND=1
+ # fi
+ # if [ ${FOUND} -eq 1 ]; then
+ # LogText "Result: found one or more Rsh Trust Files"
+ # Display --indent 4 --text "- Checking presence of Rsh Trust Files" --result "${STATUS_SUGGESTION}" --color YELLOW
+ # ReportSuggestion ${TEST_NO} "Remove every Rsh Trust Files as they can allow unauthenticated access to a system"
+ # else
+ # LogText "Result: no Rsh Trust Files found"
+ # Display --indent 4 --text "- Checking presence of Rsh Trust Files" --result "${STATUS_OK}" --color GREEN
+ # fi
+ #fi
+#
+#################################################################################
+#
+ # 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"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check if rsh server is installed
+ LogText "Test: Checking if rsh server is installed"
+ FOUND=0
+ PACKAGES="rsh-server rsh-redone-server"
+ for PACKAGE in ${PACKAGES}; do
+ if PackageIsInstalled "${PACKAGE}"; then LogText "Package '${PACKAGE}' is installed"; FOUND=1; fi
+ done
+ if [ ${FOUND} -eq 1 ]; then
+ LogText "Result: rsh server is installed"
+ Display --indent 2 --text "- Installed rsh server package" --result "${STATUS_SUGGESTION}" --color YELLOW
+ ReportSuggestion ${TEST_NO} "Remove the rsh-server package and replace with a more secure alternative like SSH"
+ Report "insecure_service[]=rsh-server"
+ else
+ LogText "Result: rsh server is NOT installed"
+ Display --indent 2 --text "- Installed rsh server package" --result "${STATUS_OK}" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8310
+ # Description : Check if telnet client is installed
+ Register --test-no INSE-8310 --weight L --network NO --category security --description "Check if telnet client is installed"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check if telnet client is installed
+ LogText "Test: Checking if telnet client is installed"
+ if PackageIsInstalled "${PACKAGE}"; then LogText "Package '${PACKAGE}' is installed"; FOUND=1; fi
+
+ if [ ${FOUND} -eq 1 ]; then
+ LogText "Result: telnet client is installed"
+ Display --indent 2 --text "- Installed telnet client package" --result "${STATUS_FOUND}" --color YELLOW
+ # Telnet client usage might be used for troubleshooting instead of system administration
+ #ReportSuggestion ${TEST_NO} "telnet client contain numerous security exposures and have been replaced with the more secure SSH package"
+ else
+ LogText "Result: telnet client is NOT installed"
+ Display --indent 2 --text "- Installed telnet client package" --result "${STATUS_OK}" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
+ # Test : INSE-8312
+ # Description : Check if telnet server is installed
+ Register --test-no INSE-8322 --weight L --network NO --category security --description "Check if telnet server is installed"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ # Check if TFTP server is installed
+ LogText "Test: Checking if telnet server is installed"
+ FOUND=0
+ PACKAGES="telnetd telnet-server"
+ for PACKAGE in ${PACKAGES}; do
+ if PackageIsInstalled "${PACKAGE}"; then LogText "Package '${PACKAGE}' is installed"; FOUND=1; fi
+ done
+ if [ ${FOUND} -eq 1 ]; then
+ LogText "Result: telnet server is installed"
+ Display --indent 2 --text "- Installed telnet server package" --result "${STATUS_FOUND}" --color YELLOW
+ ReportSuggestion ${TEST_NO} "Removing the ${FOUND} package and replace with SSH when possible"
+ Report "insecure_service[]=telnet-server"
+ else
+ LogText "Result: telnet server is NOT installed"
+ Display --indent 2 --text "- Installed telnet server package" --result "${STATUS_NOT_FOUND}" --color GREEN
+ fi
+ fi
+#
+#################################################################################
+#
if [ ! -z "${LAUNCHCTL_BINARY}" ]; then PREQS_MET="YES"; SKIPREASON=""; else PREQS_MET="NO"; SKIPREASON="No launchctl binary on this system"; fi
Register --test-no INSE-8050 --os "macOS" --preqs-met ${PREQS_MET} --skip-reason "${SKIPREASON}" --weight M --network NO --category security --description "Check for insecure services on macOS"
if [ ${SKIPTEST} -eq 0 ]; then
diff --git a/include/tests_networking b/include/tests_networking
index 3986220b..b43970ce 100644
--- a/include/tests_networking
+++ b/include/tests_networking
@@ -370,6 +370,7 @@
# Description : Check listening ports
Register --test-no NETW-3012 --weight L --network NO --category security --description "Check listening ports"
if [ ${SKIPTEST} -eq 0 ]; then
+ DATA=""
FIND=""; FIND2=""
COUNT=0
case ${OS} in
@@ -381,24 +382,19 @@
FIND=""
fi
FIND2=""
- ;;
+ ;;
Linux)
- if [ ! -z "${NETSTATBINARY}" ]; then
+ if [ -n "${SSBINARY}" ]; then
+ DATA=$(${SSBINARY} --query=udp,tcp -plnt | awk '{ if ($1!="Netid") { print "raw,ss,v1|"$1"|"$5"|"$7"|" }}' | sed 's/pid=[0-9]\{1,\},fd=[0-9]\{1,\}//g' | sed 's/users://' | sed 's/,)//g' | tr -d '()"')
+ elif [ -n "${NETSTATBINARY}" ]; then
# UDP
FIND=$(${NETSTATBINARY} -nlp 2> /dev/null | ${GREPBINARY} "^udp" | ${AWKBINARY} '{ print $4"|"$1"|"$6"|" }' | ${SEDBINARY} 's:|[0-9]*/:|:')
# TCP
FIND2=$(${NETSTATBINARY} -nlp 2> /dev/null | ${GREPBINARY} "^tcp" | ${AWKBINARY} '{ if($6=="LISTEN") { print $4"|"$1"|"$7"|" }}' | ${SEDBINARY} 's:|[0-9]*/:|:')
else
- if [ ! "${SSBINARY}" = "" ]; then
- # UDP
- FIND=$(${SSBINARY} -u -a -n 2> /dev/null | ${AWKBINARY} '{ print $4 }' | ${GREPBINARY} -v Local)
- # TCP
- FIND2=$(${SSBINARY} -t -a -n 2> /dev/null | ${AWKBINARY} '{ print $4 }' | ${GREPBINARY} -v Local)
- else
- ReportException "${TEST_NO}:1" "netstat and ss binary missing to gather listening ports"
- fi
+ ReportException "${TEST_NO}:1" "netstat and ss binary missing to gather listening ports"
fi
- ;;
+ ;;
macOS)
if [ ! "${LSOFBINARY}" = "" ]; then
@@ -409,9 +405,7 @@
fi
# Not needed as we have a combined test
FIND2=""
- ;;
-
-
+ ;;
NetBSD)
if [ ! "${SOCKSTATBINARY}" = "" ]; then
FIND=$(${SOCKSTATBINARY} 2> /dev/null | ${AWKBINARY} '{ if ($7 ~ /\*.\*/) print $5"|"$6"|"$2"|" }' | ${SORTBINARY} -u)
@@ -419,7 +413,7 @@
FIND=""
fi
FIND2=""
- ;;
+ ;;
OpenBSD)
if [ ! "${NETSTATBINARY}" = "" ]; then
# UDP
@@ -429,13 +423,20 @@
else
ReportException "${TEST_NO}:3" "netstat missing to gather listening ports"
fi
- ;;
+ ;;
*)
# Got this exception? Provide your details and output of netstat or any other tool to determine this information.
ReportException "${TEST_NO}:2" "Unclear what method to use, to determine listening port information"
- ;;
+ ;;
esac
+ if HasData "${DATA}"; then
+ for ITEM in ${DATA}; do
+ COUNT=$((COUNT + 1))
+ Report "network_listen[]=${ITEM}"
+ done
+ fi
+
# Retrieve information from sockstat, when available
LogText "Test: Retrieving sockstat information to find listening ports"
if HasData "${FIND}"; then
@@ -453,11 +454,10 @@
Report "network_listen_port[]=${ITEM}"
done
fi
- if [ "${FIND}" = "" -a "${FIND2}" = "" ]; then
+ if [ -z "${DATA}" -a -z "${FIND}" ]; then
Display --indent 2 --text "- Getting listening ports (TCP/UDP)" --result "${STATUS_SKIPPED}" --color YELLOW
else
Display --indent 2 --text "- Getting listening ports (TCP/UDP)" --result "${STATUS_DONE}" --color GREEN
- Display --indent 6 --text "* Found ${COUNT} ports"
fi
fi
#
@@ -634,9 +634,6 @@
#################################################################################
#
-Report "dhcp_client_running=${DHCP_CLIENT_RUNNING}"
-Report "arpwatch_running=${ARPWATCH_RUNNING}"
-
WaitForKeyPress
#
diff --git a/include/tests_php b/include/tests_php
index 363321cf..76606c64 100644
--- a/include/tests_php
+++ b/include/tests_php
@@ -42,6 +42,9 @@
${ROOTDIR}etc/php5/apache2/php.ini \
${ROOTDIR}etc/php5/fpm/php.ini \
${ROOTDIR}private/etc/php.ini \
+ ${ROOTDIR}etc/php/7.2/apache2/php.ini \
+ ${ROOTDIR}etc/php/7.1/apache2/php.ini \
+ ${ROOTDIR}etc/php/7.0/apache2/php.ini \
${ROOTDIR}etc/php/7.2/cli/php.ini ${ROOTDIR}etc/php/7.2/fpm/php.ini \
${ROOTDIR}etc/php/7.1/cli/php.ini ${ROOTDIR}etc/php/7.1/fpm/php.ini \
${ROOTDIR}etc/php/7.0/cli/php.ini ${ROOTDIR}etc/php/7.0/fpm/php.ini \
diff --git a/include/tests_ports_packages b/include/tests_ports_packages
index 1426a068..2d8b997e 100644
--- a/include/tests_ports_packages
+++ b/include/tests_ports_packages
@@ -344,7 +344,7 @@
COUNT=0
PACKAGE_AUDIT_TOOL_FOUND=1
PACKAGE_AUDIT_TOOL="zypper"
- FIND=$(${ZYPPERBINARY} -n se -t package -i | ${AWKBINARY} '{ if ($1=="i") { print $3 } }')
+ FIND=$(${ZYPPERBINARY} --non-interactive -n se -t package -i | ${AWKBINARY} '{ if ($1=="i") { print $3 } }')
if [ ! -z "${FIND}" ]; then
for PKG in ${FIND}; do
COUNT=$((COUNT + 1))
@@ -365,7 +365,7 @@
if [ ! -z "${ZYPPERBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no PKGS-7330 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Querying Zypper for vulnerable packages"
if [ ${SKIPTEST} -eq 0 ]; then
- FIND=$(${ZYPPERBINARY} -n pchk | ${GREPBINARY} "(0 security patches)")
+ FIND=$(${ZYPPERBINARY} --non-interactive pchk | ${GREPBINARY} "(0 security patches)")
if [ ! -z "${FIND}" ]; then
LogText "Result: No security updates found with Zypper"
Display --indent 2 --text "- Using Zypper to find vulnerable packages" --result "${STATUS_NONE}" --color GREEN
@@ -374,7 +374,7 @@
LogText "Result: Zypper found one or more installed packages which are vulnerable."
ReportWarning ${TEST_NO} "Found one or more vulnerable packages installed"
# Unfortunately zypper does not properly give back which package it is. Usually best guess is last word on the line
- FIND=$(${ZYPPERBINARY} -n lp | ${AWKBINARY} '{ if ($5=="security" || $7=="security") { print $NF }}' | ${SEDBINARY} 's/:$//' | ${GREPBINARY} -v "^$" | ${SORTBINARY} -u)
+ FIND=$(${ZYPPERBINARY} --non-interactive lp | ${AWKBINARY} '{ if ($5=="security" || $7=="security") { print $NF }}' | ${SEDBINARY} 's/:$//' | ${GREPBINARY} -v "^$" | ${SORTBINARY} -u)
LogText "List of vulnerable packages/version:"
for PKG in ${FIND}; do
VULNERABLE_PACKAGES_FOUND=1
@@ -930,7 +930,6 @@
AddHP 1 2
done
ReportWarning ${TEST_NO} "Found one or more vulnerable packages."
- ReportSuggestion ${TEST_NO} "Use 'yum --security update' to update your system"
fi
else
LogText "Result: yum-security package not found"
@@ -1055,7 +1054,8 @@
#
# Test : PKGS-7392
# Description : Check Debian/Ubuntu vulnerable packages
- if [ -x ${ROOTDIR}usr/bin/apt-get ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
+ # Note : Skip for zypper-based systems
+ if [ -x ${ROOTDIR}usr/bin/apt-get -a -z "${ZYPPERBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
Register --test-no PKGS-7392 --os Linux --preqs-met ${PREQS_MET} --root-only YES --weight L --network YES --category security --description "Check for Debian/Ubuntu security updates"
if [ ${SKIPTEST} -eq 0 ]; then
VULNERABLE_PACKAGES_FOUND=0
@@ -1247,8 +1247,20 @@
Register --test-no PKGS-7410 --weight L --network NO --category security --description "Count installed kernel packages"
if [ ${SKIPTEST} -eq 0 ]; then
KERNELS=0
- if [ ! -z "${RPMBINARY}" ]; then
- LogText "Test: Checking how many kernel packages are installed"
+ LogText "Test: Checking how many kernel packages are installed"
+
+ if [ ! -z "${DPKGBINARY}" ]; then
+ KERNELS=$(${DPKGBINARY} -l 2> /dev/null | ${GREPBINARY} "linux-image-[0-9]" | ${WCBINARY} -l)
+ if [ ${KERNELS} -eq 0 ]; then
+ LogText "Result: found no kernels from dpkg -l output, which is unexpected"
+ ReportException "KRNL-5840:2" "Could not find any kernel packages from DPKG output"
+ elif [ ${KERNELS} -gt 5 ]; then
+ LogText "Result: found more than 5 kernel packages on the system, which might indicate lack of regular cleanups"
+ ReportSuggestion "${TEST_NO}" "Remove any unneeded kernel packages" "${KERNELS} kernels" "text:validate dpkg -l output and perform cleanup with apt autoremove"
+ else
+ LogText "Result: found ${KERNELS} kernel packages on the system, which is fine"
+ fi
+ elif [ ! -z "${RPMBINARY}" ]; then
KERNELS=$(${RPMBINARY} -q kernel 2> /dev/null | ${WCBINARY} -l)
if [ ${KERNELS} -eq 0 ]; then
LogText "Result: found no kernels from rpm -q kernel output, which is unexpected"
@@ -1256,22 +1268,77 @@
elif [ ${KERNELS} -gt 5 ]; then
LogText "Result: found more than 5 kernel packages on the system, which might indicate lack of regular cleanups"
ReportSuggestion "${TEST_NO}" "Remove any unneeded kernel packages with package-cleanup utility (--old-kernels)"
- AddHP 4 5
else
- LogText "Result: found ${KERNELS} on the system, which is fine"
- AddHP 1 1
+ LogText "Result: found ${KERNELS} kernel packages on the system, which is fine"
fi
fi
+
+ Report "installed_kernel_packages=${KERNELS}"
fi
#
#################################################################################
#
+ # Test : PKGS-7420
+ # Description : Detect toolkit to automatically download and apply upgrades
+ Register --test-no PKGS-7420 --weight L --network NO --category security --description "Detect toolkit to automatically download and apply upgrades"
+ if [ ${SKIPTEST} -eq 0 ]; then
+ UNATTENDED_UPGRADES_TOOLKIT=0
+ UNATTENDED_UPGRADES_TOOL=""
+ UNATTENDED_UPGRADES_OPTION_AVAILABLE=0
+
+ case "${OS}" in
+ "Linux")
+ case "${LINUX_VERSION}" in
+ "CentOS" | "Debian" | "Fedora" | "RHEL" | "Ubuntu")
-if [ ! -z "${INSTALLED_PACKAGES}" ]; then Report "installed_packages_array=${INSTALLED_PACKAGES}"; fi
+ UNATTENDED_UPGRADES_OPTION_AVAILABLE=1
+ # Test available tools for Linux
+ if [ -f "${ROOTDIR}bin/auter" ]; then
+ UNATTENDED_UPGRADES_TOOL="auter"
+ UNATTENDED_UPGRADES_TOOLKIT=1
+ LogText "Result: found ${UNATTENDED_UPGRADES_TOOL}"
+ Report "unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}"
+ fi
+ if [ -f "${ROOTDIR}sbin/yum-cron" ]; then
+ UNATTENDED_UPGRADES_TOOL="yum-cron"
+ UNATTENDED_UPGRADES_TOOLKIT=1
+ LogText "Result: found ${UNATTENDED_UPGRADES_TOOL}"
+ Report "unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}"
+ fi
+ if [ -f "${ROOTDIR}usr/bin/dnf-automatic" ]; then
+ UNATTENDED_UPGRADES_TOOL="dnf-automatic"
+ UNATTENDED_UPGRADES_TOOLKIT=1
+ LogText "Result: found ${UNATTENDED_UPGRADES_TOOL}"
+ Report "unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}"
+ fi
+ if [ -f "${ROOTDIR}usr/bin/unattended-upgrade" ]; then
+ UNATTENDED_UPGRADES_TOOL="unattended-upgrade"
+ UNATTENDED_UPGRADES_TOOLKIT=1
+ LogText "Result: found ${UNATTENDED_UPGRADES_TOOL}"
+ Report "unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}"
+ fi
+ ;;
+ esac
+ ;;
+ esac
-Report "package_audit_tool=${PACKAGE_AUDIT_TOOL}"
-Report "package_audit_tool_found=${PACKAGE_AUDIT_TOOL_FOUND}"
-Report "vulnerable_packages_found=${VULNERABLE_PACKAGES_FOUND}"
+ if [ ${UNATTENDED_UPGRADES_OPTION_AVAILABLE} -eq 1 ]; then
+ if [ ${UNATTENDED_UPGRADES_TOOLKIT} -eq 1 ]; then
+ AddHP 5 5
+ Display --indent 2 --text "- Toolkit for automatic upgrades (${UNATTENDED_UPGRADES_TOOL})" --result "${STATUS_FOUND}" --color GREEN
+ else
+ AddHP 1 5
+ Display --indent 2 --text "- Toolkit for automatic upgrades" --result "${STATUS_NOTFOUND}" --color YELLOW
+ LogText "Result: no toolkit for automatic updates discovered"
+ ReportSuggestion "${TEST_NO}" "Consider using a tool to automatically apply upgrades"
+ fi
+ fi
+
+ Report "unattended_upgrade_option_available=${UNATTENDED_UPGRADES_OPTION_AVAILABLE}"
+ fi
+#
+#################################################################################
+#
WaitForKeyPress
diff --git a/include/tests_shells b/include/tests_shells
index 8f9763b4..3a094ad8 100644
--- a/include/tests_shells
+++ b/include/tests_shells
@@ -31,9 +31,10 @@
# 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
@@ -68,8 +69,8 @@
#################################################################################
#
# Test : SHLL-6211
- # Description : which shells are available according /etc/shells
- Register --test-no SHLL-6211 --weight L --network NO --category security --description "Checking available and valid shells"
+ # 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
@@ -98,8 +99,8 @@
#################################################################################
#
# Test : SHLL-6220
- # Description : check for idle session killing tools or settings
- Register --test-no SHLL-6220 --weight L --network NO --category security --description "Checking available and valid shells"
+ # 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=""
diff --git a/lynis b/lynis
index 15d509ea..8cacca37 100755
--- a/lynis
+++ b/lynis
@@ -22,6 +22,11 @@
#
#################################################################################
#
+ # Code quality: don't allow using undefined variables
+ 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" "$@"
@@ -35,10 +40,10 @@
PROGRAM_AUTHOR_CONTACT="lynis-dev@cisofy.com"
# Version details
- PROGRAM_RELEASE_DATE="2019-03-21"
- PROGRAM_RELEASE_TIMESTAMP=1553157295
- PROGRAM_RELEASE_TYPE="final" # dev or final
- PROGRAM_VERSION="2.7.3"
+ PROGRAM_RELEASE_DATE="2019-06-29"
+ PROGRAM_RELEASE_TIMESTAMP=1561383761
+ PROGRAM_RELEASE_TYPE="dev" # dev or final
+ PROGRAM_VERSION="3.0.0"
# Source, documentation and license
PROGRAM_SOURCE="https://github.com/CISOfy/lynis"
@@ -55,11 +60,6 @@
DISPLAY_LANG="${LANG}" # required by function Display to deal with multi-bytes characters.
- # Code quality:
- # Set strict checking for development version for first part of code. After
- # initialization this is checked with strict profile option.
- if [ ${PROGRAM_RELEASE_TYPE} = "dev" ]; then set -u; fi
-
#
#################################################################################
#
@@ -139,8 +139,7 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta
#################################################################################
#
# Perform a basic check for permissions. After including functions, using SafePerms()
- WARN_ON_FILE_ISSUES=1
- WARN_ON_FILE_ISSUES_ASKED=0
+ IGNORE_FILE_PERMISSION_ISSUES=0
FILES_TO_CHECK="consts functions"
@@ -192,14 +191,10 @@ Make sure to execute ${PROGRAM_NAME} from untarred directory or check your insta
printf "\n Option 2) Change ownership of the related files (or full directory).\n\n Commands (full directory):\n # cd ..\n # chown -R 0:0 lynis\n # cd lynis\n # ./lynis audit system"
fi
printf "\n\n[ Press ENTER to continue, or CTRL+C to cancel ]"
- WARN_ON_FILE_ISSUES_ASKED=1
+ IGNORE_FILE_PERMISSION_ISSUES=1
read DUMMY
fi
- if [ ${WARN_ON_FILE_ISSUES_ASKED} -eq 1 ]; then
- WARN_ON_FILE_ISSUES=0
- fi
-
# Now include files if permissions are correct, or user decided to continue
. ${INCLUDEDIR}/consts
. ${INCLUDEDIR}/functions
@@ -613,6 +608,9 @@ ${NORMAL}
if [ ${EOL} -eq 1 ]; then
echo " End-of-life: ${WARNING}YES${NORMAL}"
ReportWarning "GEN-0010" "This version ${OS_VERSION} is marked end-of-life as of ${EOL_DATE}"
+ elif [ ${EOL} -eq 255 ]; then
+ # TODO - mark as item where community can provide help
+ LogText "Note: the end-of-life of '${OS_FULLNAME}' could not be checked. Entry missing in software-eol.db?"
fi
if [ ! -z "${OS_MODE}" ]; then echo " Operating system mode: ${OS_MODE}"; fi