mirror of https://github.com/CISOfy/lynis.git
Merge branch 'master' into patch_3
This commit is contained in:
commit
0bdcb57763
110
CHANGELOG.md
110
CHANGELOG.md
|
@ -1,5 +1,115 @@
|
|||
# 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 commands or switches are deprecated or removed
|
||||
- Format of all profile options converted (from key:value to key=value)
|
||||
- Non-interactive by default (use --wait option to pause between groups of tests)
|
||||
|
||||
### Security
|
||||
An important focus area for this release is on security. We added several
|
||||
measures to further tighten any possible misuse.
|
||||
|
||||
### Added
|
||||
- Security: 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: filtering out unexpected characters from profiles
|
||||
- Security: test if setuid bit is set on Lynis binary
|
||||
- New function: DisplayWarning - show a warning on the screen
|
||||
- New function: Equals - compare two strings
|
||||
- New function: Readonly - mark variable read-only (security)
|
||||
- New function: SafeFile - test file type and call permission check
|
||||
- New function: SafeInput - check for safe input (security)
|
||||
- New profile option: disable-plugin - disables a single plugin
|
||||
- New profile option: ssl-certificate-paths-to-ignore - ignore a path
|
||||
- New test: CRYP-7930 - disk or file system encryption testing
|
||||
- New test: PROC-3802 - Check presence of prelink tooling
|
||||
- New report key: openssh_daemon_running
|
||||
- New command: lynis generate systemd-units
|
||||
- Measure timing of tests and report slow tests (10+ seconds)
|
||||
|
||||
### Changed
|
||||
- Function: CheckItem - returns only exit code (ITEM_FOUND value is dropped)
|
||||
- Profiles: unused options removed
|
||||
- Profiles: message is displayed when old format "key:value" is used
|
||||
- Security: the 'nounset' (set -u) parameter is now activated by default
|
||||
- Use only locations from PATH environment variable, unless it is not defined
|
||||
- Show 'lynis generate hostids' when they are missing
|
||||
- NAME-4408 - corrected Report function call
|
||||
- NETW-3032 - small rewrite of test and extended with addrwatch
|
||||
- PROC-3602 - allow different root directory
|
||||
- PROC-3612 - show 'Not found' instead of 'OK'
|
||||
- PROC-3614 - show 'Not found' instead of 'OK'
|
||||
- SSH-7402 - detect other SSH daemons like dropbear
|
||||
- Whow changelog works again for newer versions
|
||||
- systemd service file adjusted
|
||||
- bash completion script extended
|
||||
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
## 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
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 3.x.x | :white_check_mark: |
|
||||
| 2.x.x | :white_check_mark: |
|
||||
| < 2.x | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a vulnerability, use security@cisofy.com
|
||||
|
||||
See our [security page](https://cisofy.com/security/) for more details.
|
||||
|
||||
## Preferred language
|
||||
|
||||
English
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
https://cisofy.com/security/#thanks
|
||||
|
||||
## Other
|
||||
|
||||
See the latest 'security.txt' at https://cisofy.com/.well-known/security.txt
|
|
@ -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"
|
|
@ -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
|
||||
#
|
||||
|
@ -42,5 +42,21 @@ os:Ubuntu 16.10:2017-07-01:1498860000:
|
|||
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:
|
||||
os:Ubuntu 18.10:2019-07-18:1563400800:
|
||||
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:
|
||||
|
|
15
db/tests.db
15
db/tests.db
|
@ -84,6 +84,7 @@ CONT-8107:test:performance:containers::Check number of unused Docker containers:
|
|||
CONT-8108:test:security:containers::Check file permissions for Docker files:
|
||||
CORE-1000:test:performance:system_integrity::Check all system binaries:
|
||||
CRYP-7902:test:security:crypto::Check expire date of SSL certificates:
|
||||
CRYP-7930:test:security:crypto::Determine if system uses disk or file encryption:
|
||||
DNS-1600:test:security:dns::Validating that the DNSSEC signatures are checked:
|
||||
DBS-1804:test:security:databases::Checking active MySQL process:
|
||||
DBS-1816:test:security:databases::Checking MySQL root password:
|
||||
|
@ -169,11 +170,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 +326,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:
|
||||
|
@ -332,6 +340,7 @@ PROC-3602:test:security:memory_processes:Linux:Checking /proc/meminfo for memory
|
|||
PROC-3604:test:security:memory_processes:Solaris:Query prtconf for memory details:
|
||||
PROC-3612:test:security:memory_processes::Check dead or zombie processes:
|
||||
PROC-3614:test:security:memory_processes::Check heavy IO waiting based processes:
|
||||
PROC-3802:test:security:memory_processes::Check presence of prelink tooling:
|
||||
RBAC-6272:test:security:mac_frameworks::Check grsecurity presence:
|
||||
SCHD-7702:test:security:scheduling::Check status of cron daemon:
|
||||
SCHD-7704:test:security:scheduling::Check crontab/cronjobs:
|
||||
|
|
221
default.prf
221
default.prf
|
@ -1,30 +1,33 @@
|
|||
#################################################################################
|
||||
#
|
||||
#
|
||||
# Lynis - Scan Profile (default)
|
||||
#
|
||||
# This is the default profile and contains default values.
|
||||
# Lynis - Default scan profile
|
||||
#
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
#
|
||||
# SUGGESTION
|
||||
# This profile provides Lynis with most of its initial values to perform a
|
||||
# system audit.
|
||||
#
|
||||
#
|
||||
# WARNINGS
|
||||
# ----------
|
||||
#
|
||||
# Do NOT make changes to this file, instead copy your preferred settings to
|
||||
# custom.prf and put it in the same directory as default.prf
|
||||
# Do NOT make changes to this file. Instead, copy only your changes into
|
||||
# the file custom.prf and put it in the same directory as default.prf
|
||||
#
|
||||
# To discover where your profiles are located: lynis show profiles
|
||||
#
|
||||
#
|
||||
# Lynis performs a strict check on profiles to avoid the inclusion of
|
||||
# possibly harmful injections. See include/profiles for details.
|
||||
#
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
# All empty lines or with the # prefix will be skipped
|
||||
#
|
||||
# More information about this plugin can be found in the documentation:
|
||||
# https://cisofy.com/documentation/lynis/
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Use colored output
|
||||
|
@ -33,6 +36,9 @@ colors=yes
|
|||
# Compressed uploads (set to zero when errors with uploading occur)
|
||||
compressed-uploads=yes
|
||||
|
||||
# Amount of connections in WAIT state before reporting it as a suggestion
|
||||
#connections-max-wait-state=5000
|
||||
|
||||
# Debug mode (for debugging purposes, extra data logged to screen)
|
||||
#debug=yes
|
||||
|
||||
|
@ -42,20 +48,27 @@ error-on-warnings=no
|
|||
# Use Lynis in your own language (by default auto-detected)
|
||||
language=
|
||||
|
||||
# Lynis Enterprise license key
|
||||
license-key=
|
||||
# Log tests from another guest operating system (default: yes)
|
||||
#log-tests-incorrect-os=yes
|
||||
|
||||
# Define if available NTP daemon is configured as a server or client on the network
|
||||
# values: server or client (default: client)
|
||||
#ntpd-role=client
|
||||
|
||||
# Defines the role of the system (personal, workstation or server)
|
||||
machine-role=server
|
||||
|
||||
# Ignore some stratum 16 hosts (for example when running as time source itself)
|
||||
#ntp-ignore-stratum-16-peer=127.0.0.1
|
||||
|
||||
# Profile name, will be used as title/description
|
||||
profile-name=Default Audit Template
|
||||
|
||||
# Number of seconds to pause between every test (0 is no pause)
|
||||
pause-between-tests=0
|
||||
|
||||
# Enable quick mode (no waiting for keypresses, same as --quick option)
|
||||
quick=no
|
||||
# Quick mode (do not wait for keypresses)
|
||||
quick=yes
|
||||
|
||||
# Refresh software repositories to help detecting vulnerable packages
|
||||
refresh-repositories=yes
|
||||
|
@ -76,39 +89,20 @@ skip-plugins=no
|
|||
#skip-test=SSH-7408:loglevel
|
||||
#skip-test=SSH-7408:permitrootlogin
|
||||
|
||||
# Skip Lynis upgrade availability test (default: no)
|
||||
#skip-upgrade-test=yes
|
||||
|
||||
# Locations where to search for SSL certificates (separate paths with a colon)
|
||||
ssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc/pki:/etc/postfix:/etc/ssl:/opt/psa/var/certificates:/usr/local/psa/var/certificates:/usr/local/share/ca-certificates:/var/www:/srv/www
|
||||
ssl-certificate-paths-to-ignore=/etc/letsencrypt/archive:
|
||||
|
||||
# Scan type - how deep the audit should be (light, normal or full)
|
||||
test-scan-mode=full
|
||||
|
||||
# Upload data to central server
|
||||
upload=no
|
||||
|
||||
# The hostname/IP address to receive the data
|
||||
upload-server=
|
||||
|
||||
# Provide options to cURL (or other upload tool) when uploading data.
|
||||
# upload-options=--insecure --> use HTTPS, but skip certificate check (e.g. self-signed)
|
||||
upload-options=
|
||||
|
||||
# Verbose output
|
||||
verbose=no
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# Upgrade and updating
|
||||
# --------------------
|
||||
#
|
||||
# The old settings to do automatic updating are deprecated. It is suggested to
|
||||
# use a package or deploy your the tarball via a custom script.
|
||||
#
|
||||
# The latest packages can be found at: https://packages.cisofy.com
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Skip Lynis upgrade availability test (default: no)
|
||||
#skip-upgrade-test=yes
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# Plugins
|
||||
|
@ -119,10 +113,11 @@ verbose=no
|
|||
# - Nothing happens if plugin isn't available
|
||||
# - There is no order in execution of plugins
|
||||
# - See documentation about how to use plugins and phases
|
||||
# - Some are for Lynis Enterprise users only
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Lynis Plugins (some are for Lynis Enterprise users only)
|
||||
# Lynis plugins to enable
|
||||
plugin=authentication
|
||||
plugin=compliance
|
||||
plugin=configuration
|
||||
|
@ -149,17 +144,22 @@ plugin=system-integrity
|
|||
plugin=systemd
|
||||
plugin=users
|
||||
|
||||
# Disable a particular plugin (will overrule an enabled plugin)
|
||||
#disable-plugin=authentication
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# Kernel options
|
||||
# ---------------
|
||||
# sysctl:<sysctl Key>:<Expected Value>:<Hardening Points>:<Description>:
|
||||
# configdate=, followed by:
|
||||
#
|
||||
# Sysctl key = name
|
||||
# Expected value = value of sysctl key
|
||||
# Hardening points = Number of hardening points. For most keys 1 HP will be suitable
|
||||
# Description = Text description of key
|
||||
# - Type = Set to 'sysctl'
|
||||
# - Setting = value of sysctl key (e.g. kernel.sysrq)
|
||||
# - Expected value = Preferred value for key (e.g. 0)
|
||||
# - Hardening Points = Number of hardening points (typically 1 point per key) (1)
|
||||
# - Description = Textual description about the sysctl key(Disable magic SysRQ)
|
||||
# - Related file or command = For example, sysctl -a to retrieve more details
|
||||
# - Solution field = Specifies more details or where to find them (url:URL, text:TEXT, or -)
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
|
@ -269,86 +269,58 @@ config-data=sysctl;security.bsd.hardlink_check_gid;1;1;Unprivileged processes ar
|
|||
config-data=sysctl;security.bsd.hardlink_check_uid;1;1;Unprivileged processes are not allowed to create hard links to files which are owned by other users;-;category:security;
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# Apache options
|
||||
# columns: (1)apache : (2)option : (3)value
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
apache:ServerTokens:Prod:
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# OpenLDAP options
|
||||
# columns: (1)openldap : (2)file : (3)option : (4)expected value(s)
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
openldap:slapd.conf:permissions:640-600:
|
||||
openldap:slapd.conf:owner:ldap-root:
|
||||
|
||||
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# NTP options
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Ignore some stratum 16 hosts (for example when running as time source itself)
|
||||
#ntp-ignore-stratum-16-peer=127.0.0.1
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# File/directories permissions (currently not used yet)
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Scan for exact file name match
|
||||
#[scanfiles]
|
||||
#scanfile:/etc/rc.conf:FreeBSD configuration:
|
||||
|
||||
# Scan for exact directory name match
|
||||
#[scandirs]
|
||||
#scandir:/etc:/etc directory:
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# permfile
|
||||
# ---------------
|
||||
# permfile:file name:file permissions:owner:group:action:
|
||||
# permfile=file name:file permissions:owner:group:action:
|
||||
# Action = NOTICE or WARN
|
||||
# Examples:
|
||||
# permfile:/etc/test1.dat:600:root:wheel:NOTICE:
|
||||
# permfile:/etc/test1.dat:640:root:-:WARN:
|
||||
# permfile=/etc/test1.dat:600:root:wheel:NOTICE:
|
||||
# permfile=/etc/test1.dat:640:root:-:WARN:
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
#permfile:/etc/inetd.conf:rw-------:root:-:WARN:
|
||||
#permfile:/etc/fstab:rw-r--r--:root:-:WARN:
|
||||
permfile:/etc/lilo.conf:rw-------:root:-:WARN:
|
||||
|
||||
#permfile=/etc/inetd.conf:rw-------:root:-:WARN:
|
||||
#permfile=/etc/fstab:rw-r--r--:root:-:WARN:
|
||||
permfile=/boot/grub2/grub.cfg:rw-------:root:root:WARN:
|
||||
permfile=/boot/grub/grub.cfg:rw-------:root:root:WARN:
|
||||
permfile=/boot/grub2/user.cfg:rw-------:root:root:WARN:
|
||||
permfile=/etc/at.allow:rw-------:root:-:WARN:
|
||||
permfile=/etc/at.deny:rw-------:root:-:WARN:
|
||||
permfile=/etc/cron.allow:rw-------:root:-:WARN:
|
||||
permfile=/etc/cron.deny:rw-------:root:-:WARN:
|
||||
permfile=/etc/crontab:rw-------:root:-:WARN:
|
||||
permfile=/etc/group:rw-r--r--:root:-:WARN:
|
||||
permfile=/etc/group-:rw-r--r--:root:-:WARN:
|
||||
permfile=/etc/gshadow:---------:root:-:WARN:
|
||||
permfile=/etc/gshadow-:---------:root:-:WARN:
|
||||
permfile=/etc/hosts.allow:rw-r--r--:root:root:WARN:
|
||||
permfile=/etc/hosts.deny:rw-r--r--:root:root:WARN:
|
||||
permfile=/etc/issue:rw-r--r--:root:root:WARN:
|
||||
permfile=/etc/issue.net:rw-r--r--:root:root:WARN:
|
||||
permfile=/etc/lilo.conf:rw-------:root:-:WARN:
|
||||
permfile=/etc/motd:rw-r--r--:root:root:WARN:
|
||||
permfile=/etc/passwd:rw-r--r--:root:-:WARN:
|
||||
permfile=/etc/passwd-:rw-r--r--:root:-:WARN:
|
||||
permfile=/etc/shadow:---------:root:-:WARN:
|
||||
permfile=/etc/shadow-:---------:root:-:WARN:
|
||||
permfile=/etc/ssh/sshd_config:rw-------:root:-:WARN:
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# permdir
|
||||
# ---------------
|
||||
# permdir:directory name:file permissions:owner:group:action when permissions are different:
|
||||
# permdir=directory name:file permissions:owner:group:action when permissions are different:
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
permdir:/root/.ssh:rwx------:root:-:WARN:
|
||||
|
||||
# Scan for a program/binary in BINPATHs
|
||||
#scanbinary:Rootkit Hunter:rkhunter:
|
||||
|
||||
# Amount of connections in WAIT state before reporting it as a suggestion
|
||||
#connections-max-wait-state=5000
|
||||
permdir=/root/.ssh:rwx------:root:-:WARN:
|
||||
permdir=/etc/cron.d:rwx------:root:root:WARN:
|
||||
permdir=/etc/cron.daily:rwx------:root:root:WARN:
|
||||
permdir=/etc/cron.hourly:rwx------:root:root:WARN:
|
||||
permdir=/etc/cron.weekly:rwx------:root:root:WARN:
|
||||
permdir=/etc/cron.monthly:rwx------:root:root:WARN:
|
||||
|
||||
|
||||
# Ignore some specific home directories
|
||||
|
@ -356,12 +328,6 @@ permdir:/root/.ssh:rwx------:root:-:WARN:
|
|||
# checks, like file permissions, SSH and other configuration files
|
||||
#ignore-home-dir=/home/user
|
||||
|
||||
# Do not log tests with another guest operating system (default: yes)
|
||||
#log-tests-incorrect-os=no
|
||||
|
||||
# Define if available NTP daemon is configured as a server or client on the network
|
||||
# values: server or client (default: client)
|
||||
#ntpd-role=client
|
||||
|
||||
# Allow promiscuous interfaces
|
||||
# <option>:<promiscuous interface name>:<description>:
|
||||
|
@ -395,21 +361,10 @@ permdir:/root/.ssh:rwx------:root:-:WARN:
|
|||
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# SSL certificates
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
# Locations where to search for SSL certificates
|
||||
ssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc/pki:/etc/postfix:/etc/ssl:/opt/psa/var/certificates:/usr/local/psa/var/certificates:/usr/local/share/ca-certificates:/var/www:/srv/www
|
||||
|
||||
|
||||
|
||||
#################################################################################
|
||||
#
|
||||
# Lynis Enterprise options
|
||||
# -----------------
|
||||
# ------------------------
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
|
@ -423,6 +378,9 @@ ssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc
|
|||
#hostid=40-char-hash
|
||||
#hostid2=64-char-hash
|
||||
|
||||
# Lynis Enterprise license key
|
||||
license-key=
|
||||
|
||||
# Proxy settings
|
||||
# Protocol (http, https, socks5)
|
||||
#proxy-protocol=https
|
||||
|
@ -443,9 +401,18 @@ compliance-standards=cis,hipaa,iso27001,pci-dss
|
|||
# Provide the name of the customer/client
|
||||
#system-customer-name=mycustomer
|
||||
|
||||
# Upload data to central server
|
||||
upload=no
|
||||
|
||||
# The hostname/IP address to receive the data
|
||||
upload-server=
|
||||
|
||||
# Provide options to cURL (or other upload tool) when uploading data.
|
||||
# upload-options=--insecure (use HTTPS, but skip certificate check for self-signed certificates)
|
||||
upload-options=
|
||||
|
||||
# Link one or more tags to a system
|
||||
#tags=db,production,ssn-1304
|
||||
|
||||
|
||||
|
||||
#EOF
|
||||
|
|
|
@ -3,6 +3,5 @@
|
|||
|
||||
debug=yes
|
||||
developer-mode=yes
|
||||
quick=yes
|
||||
strict=yes
|
||||
verbose=yes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# bash completion for lynis
|
||||
|
||||
# version 1.0.0 (22 September 2014)
|
||||
# version 1.0.1 (2019-07-13)
|
||||
# Michael Boelen <michael.boelen@cisofy.com>
|
||||
|
||||
# lynis(8) completion
|
||||
|
@ -10,7 +10,7 @@ _lynis()
|
|||
# opts nodig nosig
|
||||
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref cur prev
|
||||
_get_comp_words_by_ref cur prev words
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ]; then
|
||||
# first parameter on line
|
||||
|
@ -19,24 +19,134 @@ _lynis()
|
|||
COMPREPLY=( $( compgen -W '--help --info --version' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W 'audit --help --info --version' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W 'audit generate show' -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
return 0
|
||||
elif [ $COMP_CWORD -eq 4 ]; then
|
||||
# Stop after some specifics
|
||||
if [ "${COMP_WORDS[1]}" = "show" -a "${COMP_WORDS[2]}" = "details" ]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check previous argument to share the available options
|
||||
case $prev in
|
||||
audit)
|
||||
COMPREPLY=( $( compgen -W 'dockerfile system ' -- "$cur" ) )
|
||||
;;
|
||||
|
||||
show)
|
||||
COMPREPLY=( $( compgen -W 'help version ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W 'categories changelog commands dbdir details environment eol groups help hostids includedir language license logfile man options os pidfile plugindir profiles release releasedate report settings tests version workdir ' -- "$cur" ) )
|
||||
;;
|
||||
|
||||
# Related items to show (lynis show XYZ)
|
||||
categories)
|
||||
return 0
|
||||
;;
|
||||
changelog)
|
||||
return 0
|
||||
;;
|
||||
commands)
|
||||
return 0
|
||||
;;
|
||||
dbdir)
|
||||
return 0
|
||||
;;
|
||||
details)
|
||||
local dbfile=""
|
||||
local dirs="/data/development/lynis /usr/local/lynis /usr/share/lynis"
|
||||
for d in ${dirs}; do
|
||||
if [ -f "${d}/db/tests.db" ]; then
|
||||
local dbfile="/data/development/lynis/db/tests.db"
|
||||
fi
|
||||
done
|
||||
if [ -f "${dbfile}" ]; then
|
||||
local suggestions=($(compgen -W "$(awk -F: '$1 ~ /^[A-Z]/ {print $1}' ${dbfile})" -- "${cur}"))
|
||||
COMPREPLY=("${suggestions[@]}")
|
||||
else
|
||||
COMPREPLY=($(compgen -W "TEST-1234" -- "$cur"))
|
||||
fi
|
||||
;;
|
||||
environment)
|
||||
return 0
|
||||
;;
|
||||
eol)
|
||||
return 0
|
||||
;;
|
||||
groups)
|
||||
return 0
|
||||
;;
|
||||
help)
|
||||
return 0
|
||||
;;
|
||||
hostids)
|
||||
if [ "${COMP_WORDS[1]}" = "generate" -a "${COMP_WORDS[2]}" = "hostids" ]; then
|
||||
COMPREPLY=($(compgen -W "save" -- "$cur"))
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
includedir)
|
||||
return 0
|
||||
;;
|
||||
language)
|
||||
return 0
|
||||
;;
|
||||
license)
|
||||
return 0
|
||||
;;
|
||||
logfile)
|
||||
return 0
|
||||
;;
|
||||
man)
|
||||
return 0
|
||||
;;
|
||||
options)
|
||||
return 0
|
||||
;;
|
||||
os)
|
||||
return 0
|
||||
;;
|
||||
pidfile)
|
||||
return 0
|
||||
;;
|
||||
plugindir)
|
||||
return 0
|
||||
;;
|
||||
profiles)
|
||||
return 0
|
||||
;;
|
||||
release)
|
||||
return 0
|
||||
;;
|
||||
releasedate)
|
||||
return 0
|
||||
;;
|
||||
report)
|
||||
return 0
|
||||
;;
|
||||
settiings)
|
||||
return 0
|
||||
;;
|
||||
tests)
|
||||
return 0
|
||||
;;
|
||||
version)
|
||||
return 0
|
||||
;;
|
||||
workdir)
|
||||
return 0
|
||||
;;
|
||||
|
||||
generate)
|
||||
COMPREPLY=( $( compgen -W 'hostids ' -- "$cur" ) )
|
||||
;;
|
||||
|
||||
# Options
|
||||
--auditor)
|
||||
COMPREPLY=( '"Mr. Auditor"' )
|
||||
return 0
|
||||
#return 0
|
||||
;;
|
||||
--check-update|--help|--info|--version)
|
||||
# all other options are noop with this command
|
||||
|
|
|
@ -5,19 +5,26 @@
|
|||
#################################################################################
|
||||
#
|
||||
# - Adjust path to link to location where Lynis binary is installed
|
||||
# - Place this file together with the timer file in systemd directory
|
||||
# - Run: systemctl enable lynis.service
|
||||
#
|
||||
# - Place this file together with the lynis.timer file in the related
|
||||
# systemd directory (e.g. /etc/systemd/system/)
|
||||
#
|
||||
# - See details in lynis.timer file
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
[Unit]
|
||||
Description=Lynis security audit and vulnerability scan
|
||||
Description=Security audit and vulnerability scanner
|
||||
Documentation=https://cisofy.com/docs/
|
||||
|
||||
[Service]
|
||||
Nice=19
|
||||
IOSchedulingClass=best-effort
|
||||
IOSchedulingPriority=7
|
||||
Type=simple
|
||||
ExecStart=/path/to/lynis -c --cronjob
|
||||
ExecStart=/path/to/lynis audit system --cronjob
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
#EOF
|
||||
|
|
|
@ -4,17 +4,23 @@
|
|||
#
|
||||
#################################################################################
|
||||
#
|
||||
# - Place this file together with the service file in systemd directory
|
||||
# - Run: systemctl enable lynis.timer
|
||||
# systemctl start lynis.service
|
||||
# - Place this file together with the lynis.service file in the related
|
||||
# systemd directory (e.g. /etc/systemd/system)
|
||||
#
|
||||
# - Tell systemd you made changes
|
||||
# systemctl daemon-reload
|
||||
#
|
||||
# - Enable and start the timer (so no reboot is needed):
|
||||
# systemctl enable --now lynis.timer
|
||||
#
|
||||
#################################################################################
|
||||
|
||||
[Unit]
|
||||
Description=Daily run for Lynis security audit and vulnerability scan
|
||||
Description=Daily timer for the Lynis security audit and vulnerability scanner
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
RandomizedDelaySec=1800
|
||||
Persistent=false
|
||||
|
||||
[Install]
|
||||
|
|
|
@ -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}" ;;
|
||||
|
@ -254,6 +279,7 @@
|
|||
LogText "Result: Directory ${SCANDIR} does NOT exist"
|
||||
fi
|
||||
done
|
||||
|
||||
# unset SORTED_BIN_PATHS
|
||||
BINARY_SCAN_FINISHED=1
|
||||
BINARY_PATHS_FOUND=$(echo ${BINARY_PATHS_FOUND} | sed 's/^, //g' | sed 's/ //g')
|
||||
|
@ -261,10 +287,35 @@
|
|||
LogText "Result: found ${COUNT} binaries"
|
||||
Report "binaries_count=${COUNT}"
|
||||
Report "binary_paths=${BINARY_PATHS_FOUND}"
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
else
|
||||
LogText "Result: checking of binaries skipped in this mode"
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
#================================================================================
|
||||
# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
|
||||
|
|
|
@ -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
|
||||
|
@ -84,6 +86,7 @@ unset LANG
|
|||
CONTAINER_TYPE=""
|
||||
CREATE_REPORT_FILE=1
|
||||
CSUMBINARY=""
|
||||
CURRENT_TS=0
|
||||
CUSTOM_URL_APPEND=""
|
||||
CUSTOM_URL_PREPEND=""
|
||||
CUSTOM_URL_PROTOCOL=""
|
||||
|
@ -94,13 +97,17 @@ unset LANG
|
|||
DEBSECANBINARY=""
|
||||
DEBSUMSBINARY=""
|
||||
DEVELOPER_MODE=0
|
||||
DISABLED_PLUGINS=""
|
||||
DISCOVERED_BINARIES=""
|
||||
DMIDECODEBINARY=""
|
||||
DNFBINARY=""
|
||||
DOCKERBINARY=""
|
||||
DOCKER_DAEMON_RUNNING=0
|
||||
DPKGBINARY=""
|
||||
ECHOCMD=""
|
||||
ERROR_ON_WARNINGS=0
|
||||
EQUERYBINARY=""
|
||||
EXIMBINARY=""
|
||||
FAIL2BANBINARY=""
|
||||
FILEBINARY=""
|
||||
FILEVALUE=""
|
||||
|
@ -210,6 +217,8 @@ unset LANG
|
|||
PLUGIN_PHASE=0
|
||||
POSTFIXBINARY=""
|
||||
POSTGRES_RUNNING=0
|
||||
PREVIOUS_TEST="No test ID"
|
||||
PREVIOUS_TS=0
|
||||
PRIVILEGED=0
|
||||
PROFILES=""
|
||||
PROFILEVALUE=""
|
||||
|
@ -248,8 +257,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=""
|
||||
|
@ -257,6 +268,7 @@ unset LANG
|
|||
SSHKEYSCANBINARY=""
|
||||
SSHKEYSCANFOUND=0
|
||||
SSL_CERTIFICATE_PATHS=""
|
||||
SSL_CERTIFICATE_PATHS_TO_IGNORE=""
|
||||
STUNNELBINARY=""
|
||||
SYSLOGNGBINARY=""
|
||||
SYSTEMCTLBINARY=""
|
||||
|
@ -270,6 +282,7 @@ unset LANG
|
|||
TESTS_EXECUTED=""
|
||||
TESTS_SKIPPED=""
|
||||
TMPFILE=""
|
||||
TOMOYOINITBINARY=""
|
||||
TOOLTIP_SHOWED=0
|
||||
TOTAL_SUGGESTIONS=0
|
||||
TOTAL_WARNINGS=0
|
||||
|
@ -340,7 +353,8 @@ unset LANG
|
|||
#################################################################################
|
||||
#
|
||||
|
||||
# Normal color names
|
||||
# Normal color names (BG will color background)
|
||||
BG_BLUE="$(printf '\033[0;44m')"
|
||||
CYAN="$(printf '\033[0;36m')"
|
||||
BLUE="$(printf '\033[0;34m')"
|
||||
BROWN="$(printf '\033[0;33m')"
|
||||
|
@ -354,15 +368,13 @@ unset LANG
|
|||
YELLOW="$(printf '\033[1;33m')"
|
||||
WHITE="$(printf '\033[1;37m')"
|
||||
|
||||
# Markup
|
||||
# Special markup
|
||||
BOLD="${WHITE}"
|
||||
|
||||
# With background
|
||||
BG_BLUE="$(printf '\033[0;44m')"
|
||||
NORMAL="$(printf '\033[0m')"
|
||||
|
||||
# Semantic names
|
||||
BG_WARNING="$(printf '\033[30;43m')" # Yellow background with grey text
|
||||
HEADER="${WHITE}"
|
||||
NORMAL="$(printf '\033[0m')"
|
||||
WARNING="${RED}"
|
||||
SECTION="${YELLOW}"
|
||||
NOTICE="${YELLOW}"
|
||||
|
|
|
@ -242,13 +242,9 @@
|
|||
fi
|
||||
else
|
||||
echo "${RED}Error${NORMAL}: No hostid and/or hostid2 found. Can not upload report file."
|
||||
echo "Suggested command: lynis show hostids"
|
||||
echo "Suggested command: lynis generate hostids --save"
|
||||
echo ""
|
||||
echo "If hostid2 is the only ID that is missing, use the following step:"
|
||||
echo "Create hash and add it to custom.prf"
|
||||
echo "echo \"hostid2=\$(cat /dev/urandom | tr -dc 'a-f0-9' | fold -w 64 | head -n 1)\" >> /etc/lynis/custom.prf"
|
||||
echo ""
|
||||
echo "Note: do not replicate this ID to other systems, as it needs to be unique per system"
|
||||
echo "Note: do not replicate the values to other systems, as it needs to be unique per system"
|
||||
|
||||
# Quit
|
||||
ExitFatal
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
# DisplayError Show an error on screen
|
||||
# DisplayManual Output text to screen without any layout
|
||||
# DisplayToolTip Show a tip for improving usage of the tool
|
||||
# DisplayWarning Show a clear warning on screen
|
||||
# Equals Compares two strings
|
||||
# ExitClean Stop the program (cleanly), with exit code 0
|
||||
# ExitCustom Stop the program (cleanly), with custom exit code
|
||||
# ExitFatal Stop the program (cleanly), with exit code 1
|
||||
|
@ -74,6 +76,7 @@
|
|||
# ParseTestValues Parse a set of values
|
||||
# PortIsListening Check if machine is listening on specified protocol and port
|
||||
# Progress Show progress on screen
|
||||
# Readonly Mark a variable as read-only data
|
||||
# Register Register a test (for logging and execution)
|
||||
# RandomString Show a random string
|
||||
# RemoveColors Reset all colors
|
||||
|
@ -85,7 +88,9 @@
|
|||
# ReportManual Log manual actions to report file
|
||||
# ReportSuggestion Add a suggestion to report file
|
||||
# ReportWarning Add a warning and priority to report file
|
||||
# SafeFile Security tests to perform on a file before using it
|
||||
# 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
|
||||
|
@ -114,7 +119,8 @@
|
|||
# Name : AddHP()
|
||||
# Description : Add hardening points and count them
|
||||
#
|
||||
# Input : $1 = points to add, $2 = maximum points for this item
|
||||
# Parameters : $1 = points to add (0 or higher)
|
||||
# $2 = maximum points (at least value of $1 or higher)
|
||||
# Returns : <nothing>
|
||||
# Usage : AddHP 1 3
|
||||
################################################################################
|
||||
|
@ -135,7 +141,9 @@
|
|||
# Name : AddSetting()
|
||||
# Description : Addition of a setting for display with 'lynis show settings'
|
||||
#
|
||||
# Input : $1 = setting, $2 = value, $3 description
|
||||
# Parameters : $1 = setting
|
||||
# $2 = value
|
||||
# $3 = description
|
||||
# Returns : <nothing>
|
||||
# Usage : AddSetting debug 1 'Debug mode'
|
||||
################################################################################
|
||||
|
@ -159,7 +167,7 @@
|
|||
TEMP_SETTINGS_FILE="${TEMP_FILE}"
|
||||
cat ${SETTINGS_FILE} > ${TEMP_SETTINGS_FILE}
|
||||
sed -e '/^'"${SETTING}"';/d' ${TEMP_SETTINGS_FILE} > ${SETTINGS_FILE}
|
||||
rm ${TEMP_SETTINGS_FILE}
|
||||
rm "${TEMP_SETTINGS_FILE}"
|
||||
echo "${SETTING};${VALUE};${DESCRIPTION};" >> ${SETTINGS_FILE}
|
||||
fi
|
||||
else
|
||||
|
@ -172,7 +180,7 @@
|
|||
# Name : AddSystemGroup()
|
||||
# Description : Adds a system to a group, which can be used for categorizing
|
||||
#
|
||||
# Input : Group name
|
||||
# Parameters : $1 = group name
|
||||
# Returns : <nothing>
|
||||
# Usage : AddSystemGroup "test"
|
||||
################################################################################
|
||||
|
@ -186,13 +194,13 @@
|
|||
# Name : CheckFilePermissions()
|
||||
# Description : Check file permissions
|
||||
#
|
||||
# Input : full path to file or directory
|
||||
# Parameters : Full path to file or directory
|
||||
# Returns : PERMS (FILE_NOT_FOUND | OK | BAD)
|
||||
# Notes : This function might be replaced in future
|
||||
################################################################################
|
||||
|
||||
CheckFilePermissions() {
|
||||
CHECKFILE=$1
|
||||
CHECKFILE="$1"
|
||||
if [ ! -d ${CHECKFILE} -a ! -f ${CHECKFILE} ]; then
|
||||
PERMS="FILE_NOT_FOUND"
|
||||
else
|
||||
|
@ -213,13 +221,13 @@
|
|||
# Name : CheckItem()
|
||||
# Description : Check if a specific item exists in the report
|
||||
#
|
||||
# Input : $1 = key, $2 = value
|
||||
# Returns : ITEM_FOUND
|
||||
# Usage : CheckItem "key" "value"
|
||||
# Parameters : $1 = key
|
||||
# $2 = value
|
||||
# Returns : True (0) or False (1)
|
||||
# Usage : if CheckItem "key" "value"; then ....; fi
|
||||
################################################################################
|
||||
|
||||
CheckItem() {
|
||||
ITEM_FOUND=0
|
||||
RETVAL=255
|
||||
if [ $# -eq 2 ]; then
|
||||
# Don't search in /dev/null, it's too empty there
|
||||
|
@ -228,7 +236,6 @@
|
|||
LogText "Test: search string $2 in earlier discovered results"
|
||||
FIND=$(egrep "^$1(\[\])?=" ${REPORTFILE} | egrep "$2")
|
||||
if HasData "${FIND}"; then
|
||||
ITEM_FOUND=1
|
||||
RETVAL=0
|
||||
LogText "Result: found search string (result: $FIND)"
|
||||
else
|
||||
|
@ -248,6 +255,7 @@
|
|||
################################################################################
|
||||
# Name : CheckUpdates()
|
||||
# Description : Determine if there is an update available
|
||||
#
|
||||
# Returns : <nothing>
|
||||
# Usage : CheckUpdates
|
||||
# Use PROGRAM_LV (latest version) and compare it with actual version (PROGRAM_AC)
|
||||
|
@ -282,8 +290,9 @@
|
|||
|
||||
################################################################################
|
||||
# Name : CleanUp()
|
||||
# Description : Cleanup service
|
||||
# Returns : <nothing>
|
||||
# Description : Delete PID and temporary files, stop execution (exit code 1)
|
||||
#
|
||||
# Usage : this function is triggered by a manual break by user
|
||||
################################################################################
|
||||
|
||||
CleanUp() {
|
||||
|
@ -298,7 +307,8 @@
|
|||
################################################################################
|
||||
# Name : ContainsString()
|
||||
# Description : Search a specific string (or regular expression) in another
|
||||
# Returns : (0 - True, 1 - False)
|
||||
#
|
||||
# Returns : True (0) or False (1)
|
||||
# Usage : if ContainsString "needle" "there is a needle in the haystack"; echo "Found"; else "Not found"; fi
|
||||
################################################################################
|
||||
|
||||
|
@ -313,11 +323,9 @@
|
|||
|
||||
################################################################################
|
||||
# Name : CountTests()
|
||||
# Description : Count the number of tests performed
|
||||
# Description : Counter for the number of tests performed
|
||||
#
|
||||
# Input : <nothing>
|
||||
# Returns : <nothing>
|
||||
# Usage : CountTests
|
||||
# Usage : Call CountTests to increase number by 1
|
||||
################################################################################
|
||||
|
||||
CountTests() {
|
||||
|
@ -329,7 +337,6 @@
|
|||
# Name : CreateTempFile()
|
||||
# Description : Creates a temporary file
|
||||
#
|
||||
# Input : <nothing>
|
||||
# Returns : TEMP_FILE (variable)
|
||||
# Usage : CreateTempFile
|
||||
# if [ ! "${TEMP_FILE}" = "" ]; then
|
||||
|
@ -361,7 +368,7 @@
|
|||
# Name : DirectoryExists()
|
||||
# Description : Check if a directory exists
|
||||
#
|
||||
# Returns : 0 (directory exists), 1 (directory does not exist)
|
||||
# Returns : True (0) or False (1)
|
||||
# Usage : if DirectoryExists; then echo "it exists"; else echo "It does not exist"; fi
|
||||
################################################################################
|
||||
|
||||
|
@ -605,6 +612,46 @@
|
|||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : DisplayWarning
|
||||
# Description : Show a warning on the screen
|
||||
#
|
||||
# Input : $1 = text
|
||||
# Returns : <nothing>
|
||||
################################################################################
|
||||
|
||||
DisplayWarning() {
|
||||
if [ ${CRONJOB} -eq 0 ]; then
|
||||
printf "\n"
|
||||
${ECHOCMD:-echo} " ${BG_WARNING}[WARNING]${NORMAL}: $1${NORMAL}"
|
||||
printf "\n"
|
||||
else
|
||||
${ECHOCMD} " [WARNING]: $1"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : Equals()
|
||||
# Description : Compare two strings
|
||||
#
|
||||
# Returns : (0 - True, 1 - False)
|
||||
# Usage : if Equals "${MYDIR}" "/etc"; then echo "Found"; else "Not found"; fi
|
||||
################################################################################
|
||||
|
||||
Equals() {
|
||||
RETVAL=1
|
||||
if [ $# -ne 2 ]; then ReportException "Equals" "Incorrect number of arguments for $0 function"; fi
|
||||
|
||||
# Strip any strange control characters
|
||||
INPUT1=$(echo $1 | tr -d '[:cntrl:]<>' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/:space:/ /g')
|
||||
INPUT2=$(echo $2 | tr -d '[:cntrl:]<>' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/:space:/ /g')
|
||||
if [ "${INPUT1}" = "${INPUT2}" ]; then RETVAL=0; fi
|
||||
|
||||
return ${RETVAL}
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : ExitClean()
|
||||
# Description : Perform a normal exit of the program, and clean up resources
|
||||
|
@ -659,9 +706,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 +852,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 +1168,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 +1343,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 +1452,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 +1763,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 +1778,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 +2056,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
|
||||
|
@ -2089,6 +2162,24 @@
|
|||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : Readonly()
|
||||
# Description : Mark a variable as read-only data
|
||||
# Returns : nothing
|
||||
################################################################################
|
||||
|
||||
Readonly() {
|
||||
if [ $# -eq 1 ]; then
|
||||
if type -t typeset; then
|
||||
typeset -r $1
|
||||
else
|
||||
Debug "No typeset available to mark variable '$1' as read-only variable"
|
||||
fi
|
||||
else
|
||||
ExitFatal "Expected 1 parameter, received none or multiple"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : Register()
|
||||
|
@ -2096,6 +2187,19 @@
|
|||
# Returns : SKIPTEST (0 or 1)
|
||||
################################################################################
|
||||
|
||||
GetTimestamp() {
|
||||
ts=0
|
||||
case "${OS}" in
|
||||
"Linux")
|
||||
ts=$(date "+%s%N")
|
||||
;;
|
||||
*)
|
||||
ts=$(date "+%s")
|
||||
;;
|
||||
esac
|
||||
echo $ts
|
||||
}
|
||||
|
||||
Register() {
|
||||
# Do not insert a log break, if previous test was not logged
|
||||
if [ ${SKIPLOGTEST} -eq 0 ]; then LogTextBreak; fi
|
||||
|
@ -2163,6 +2267,35 @@
|
|||
shift
|
||||
done
|
||||
|
||||
# Measure timing
|
||||
CURRENT_TS=$(GetTimestamp)
|
||||
if [ ${PREVIOUS_TS} -gt 0 ]; then
|
||||
SLOW_TEST=0
|
||||
TIME_THRESHOLD=10 # seconds
|
||||
|
||||
# Calculate timing and determine if we use seconds or nanoseconds (more precise)
|
||||
TIME_DIFF=$((${CURRENT_TS} - ${PREVIOUS_TS}))
|
||||
if [ ${CURRENT_TS} -gt 1000000000000000000 ]; then
|
||||
TIME_DIFF_FORMAT="nanoseconds"
|
||||
TIME_THRESHOLD=$((${TIME_THRESHOLD} * 1000000000))
|
||||
if [ ${TIME_DIFF} -gt ${TIME_THRESHOLD} ]; then
|
||||
SLOW_TEST=1
|
||||
# Convert back to seconds for readability
|
||||
TIME_DIFF_FORMAT="seconds"
|
||||
TIME_DIFF=$(echo ${TIME_DIFF} | ${AWKBINARY} '{printf "%f",$1/1000000000}')
|
||||
fi
|
||||
else
|
||||
TIME_DIFF_FORMAT="seconds"
|
||||
if [ ${TIME_DIFF} -gt ${TIME_THRESHOLD} ]; then
|
||||
SLOW_TEST=1
|
||||
fi
|
||||
fi
|
||||
if [ ${SLOW_TEST} -eq 1 ]; then
|
||||
DisplayWarning "Test ${PREVIOUS_TEST} had a long execution: ${TIME_DIFF} ${TIME_DIFF_FORMAT}"
|
||||
Report "slow_test[]=${PREVIOUS_TEST},${TIME_DIFF}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Skip test if it's configured in profile (old style)
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
FIND=$(echo "${TEST_SKIP_ALWAYS}" | grep "${TEST_NO}" | tr '[:lower:]' '[:upper:]')
|
||||
|
@ -2235,6 +2368,10 @@
|
|||
TESTS_SKIPPED="${TEST_NO}|${TESTS_SKIPPED}"
|
||||
fi
|
||||
unset SKIPREASON
|
||||
|
||||
# Save timestamp for next time the Register function is called
|
||||
PREVIOUS_TEST="${TEST_NO}"
|
||||
PREVIOUS_TS="${CURRENT_TS}"
|
||||
}
|
||||
|
||||
|
||||
|
@ -2262,6 +2399,7 @@
|
|||
|
||||
# Colors with background
|
||||
BG_BLUE=""
|
||||
BG_WARNING=""
|
||||
|
||||
# Semantic names
|
||||
BAD=""
|
||||
|
@ -2276,14 +2414,15 @@
|
|||
|
||||
################################################################################
|
||||
# Name : RemovePIDFile()
|
||||
# Description : When defined, remove the file storing the process ID
|
||||
################################################################################
|
||||
|
||||
# Remove PID file
|
||||
RemovePIDFile() {
|
||||
# Test if PIDFILE is defined, before checking file presence
|
||||
if [ ! "${PIDFILE}" = "" ]; then
|
||||
if [ -f ${PIDFILE} ]; then
|
||||
rm -f $PIDFILE;
|
||||
if [ ! -z "${PIDFILE}" ]; then
|
||||
if [ -f "${PIDFILE}" ]; then
|
||||
rm -f "${PIDFILE}"
|
||||
LogText "PID file removed (${PIDFILE})"
|
||||
else
|
||||
LogText "PID file not found (${PIDFILE})"
|
||||
|
@ -2294,6 +2433,7 @@
|
|||
|
||||
################################################################################
|
||||
# Name : RemoveTempFiles()
|
||||
# Description : When created, delete any temporary file
|
||||
################################################################################
|
||||
|
||||
# Remove any temporary files
|
||||
|
@ -2304,10 +2444,10 @@
|
|||
for FILE in ${TEMP_FILES}; do
|
||||
# Temporary files should be in /tmp
|
||||
TMPFILE=$(echo ${FILE} | egrep "^/tmp/lynis" | grep -v "\.\.")
|
||||
if [ ! "${TMPFILE}" = "" ]; then
|
||||
if [ -f ${TMPFILE} ]; then
|
||||
if [ ! -z "${TMPFILE}" ]; then
|
||||
if [ -f "${TMPFILE}" ]; then
|
||||
LogText "Action: removing temporary file ${TMPFILE}"
|
||||
rm -f ${TMPFILE}
|
||||
rm -f "${TMPFILE}"
|
||||
else
|
||||
LogText "Info: temporary file ${TMPFILE} was already removed"
|
||||
fi
|
||||
|
@ -2323,6 +2463,7 @@
|
|||
|
||||
################################################################################
|
||||
# Name : Report()
|
||||
# Description : Store data in the report file
|
||||
################################################################################
|
||||
|
||||
Report() {
|
||||
|
@ -2397,12 +2538,14 @@
|
|||
|
||||
################################################################################
|
||||
# Name : ReportException()
|
||||
# Description : Store an exceptional event in the report
|
||||
#
|
||||
# Parameters : $1 = test ID + colon + 2 numeric characters (TEST-1234:01)
|
||||
# $2 = string (text)
|
||||
################################################################################
|
||||
|
||||
# Log exceptions
|
||||
ReportException() {
|
||||
# 1 parameters
|
||||
# <ID>:<2 char numeric>|text|
|
||||
Report "exception_event[]=$1|$2|"
|
||||
LogText "Exception: test has an exceptional event ($1) with text $2"
|
||||
}
|
||||
|
@ -2410,11 +2553,12 @@
|
|||
|
||||
################################################################################
|
||||
# Name : ReportManual()
|
||||
# Description : Add an item to the report that requires manual intervention
|
||||
#
|
||||
# Parameters : $1 = string (text)
|
||||
################################################################################
|
||||
|
||||
# Log manual actions to report file
|
||||
ReportManual() {
|
||||
# 1 parameter: Text
|
||||
Report "manual_event[]=$1"
|
||||
LogText "Manual: one or more manual actions are required for further testing of this control/plugin"
|
||||
}
|
||||
|
@ -2422,20 +2566,20 @@
|
|||
|
||||
################################################################################
|
||||
# Name : ReportSuggestion()
|
||||
# Description : Log a suggestion to the report file
|
||||
#
|
||||
# Parameters : <ID> <Suggestion> <Details> <Solution>
|
||||
# $1 = Test ID - Lynis ID (use CUST-.... for your own tests)
|
||||
# $2 = Suggestion - Suggestion text to be displayed
|
||||
# $3 = Details - Specific item or details
|
||||
# $4 = Solution - Optional link for additional information:
|
||||
# * url:https://example.org/how-to-solve-link
|
||||
# * text:Additional explanation
|
||||
# * - (dash) for none
|
||||
################################################################################
|
||||
|
||||
# Log suggestions to report file
|
||||
ReportSuggestion() {
|
||||
TOTAL_SUGGESTIONS=$((TOTAL_SUGGESTIONS + 1))
|
||||
# 4 parameters
|
||||
# <ID> <Suggestion> <Details> <Solution>
|
||||
# <ID> Lynis ID (use CUST-.... for your own tests)
|
||||
# <Suggestion> Suggestion text to be displayed
|
||||
# <Details> Specific item or details
|
||||
# <Solution> Optional link for additional information:
|
||||
# * url:http://site/link
|
||||
# * text:Additional explanation
|
||||
# * - for none
|
||||
if [ $# -eq 0 ]; then echo "Not enough arguments provided for function ReportSuggestion"; ExitFatal; fi
|
||||
if [ $# -ge 1 ]; then TEST="$1"; else TEST="UNKNOWN"; fi
|
||||
if [ $# -ge 2 ]; then MESSAGE="$2"; else MESSAGE="UNKNOWN"; fi
|
||||
|
@ -2449,9 +2593,9 @@
|
|||
|
||||
################################################################################
|
||||
# Name : ReportWarning()
|
||||
# Description : Log a warning to the report file
|
||||
################################################################################
|
||||
|
||||
# Log warning to report file
|
||||
ReportWarning() {
|
||||
TOTAL_WARNINGS=$((TOTAL_WARNINGS + 1))
|
||||
# Old style
|
||||
|
@ -2484,76 +2628,180 @@
|
|||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# 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 : SafeFile()
|
||||
# Description : Check if a file is safe to use
|
||||
#
|
||||
################################################################################
|
||||
|
||||
SafeFile() {
|
||||
unsafe=0
|
||||
if [ $# -ne 1 ]; then
|
||||
ExitFatal "No argument or too many arguments provided to SafeFile()"
|
||||
else
|
||||
FILE="$1"
|
||||
|
||||
# Generic checks
|
||||
if [ -g "${FILE}" ]; then
|
||||
LogText "Security alert: file has setgid attribute"
|
||||
unsafe=1
|
||||
# sticky bit
|
||||
elif [ -k "${FILE}" ]; then
|
||||
LogText "Security alert: file has sticky bit"
|
||||
unsafe=1
|
||||
# symbolic link
|
||||
elif [ -L "${FILE}" ]; then
|
||||
LogText "Security alert: file is a symbolic link"
|
||||
unsafe=1
|
||||
elif [ -f "${FILE}" ]; then
|
||||
LogText "Security check: file is normal"
|
||||
else
|
||||
unsafe=1
|
||||
fi
|
||||
|
||||
# Perform additional checks based on privilege level
|
||||
if [ ${PRIVILEGED} -eq 0 ]; then
|
||||
# File is not owned by active user, but still able to write
|
||||
if [ ! -O "${FILE}" -a -w "${FILE}" ]; then
|
||||
unsafe=1
|
||||
LogText "Security alert: file is not owned by active user, but can write to it"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check file permissions
|
||||
if ! SafePerms "${FILE}"; then
|
||||
unsafe=1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
return ${unsafe}
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Name : SafePerms()
|
||||
# Return : 0 (file OK) or break
|
||||
# Description : Check if a file has safe permissions to be used
|
||||
#
|
||||
# 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 [ ! -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)
|
||||
|
||||
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=$(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 }')
|
||||
|
||||
# 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
|
||||
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
|
||||
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
|
||||
# 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
|
||||
|
||||
# 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
|
||||
# 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}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2561,14 +2809,15 @@
|
|||
# Name : SearchItem()
|
||||
# Description : Search if a specific string exists in in a file
|
||||
#
|
||||
# Input : $1 = search key (string), $2 = file (string), $3 and later
|
||||
# are optional arguments
|
||||
# Parameters : $1 = search key (string)
|
||||
# $2 = file (string)
|
||||
# $3 = optional arguments:
|
||||
# --sensitive - don't store results in log
|
||||
# Returns : True (0) or False (1)
|
||||
################################################################################
|
||||
|
||||
SearchItem() {
|
||||
PERFORM_SCAN=0
|
||||
ITEM_FOUND=0
|
||||
MASK_LOG=0
|
||||
RETVAL=1
|
||||
if [ $# -lt 2 ]; then
|
||||
|
@ -2596,8 +2845,7 @@
|
|||
# Check if we can find the main type (with or without brackets)
|
||||
LogText "Test: search string ${STRING} in file ${FILE}"
|
||||
FIND=$(egrep "${STRING}" ${FILE})
|
||||
if [ ! "${FIND}" = "" ]; then
|
||||
ITEM_FOUND=1
|
||||
if [ ! -z "${FIND}" ]; then
|
||||
LogText "Result: found search string '${STRING}'"
|
||||
if [ ${MASK_LOG} -eq 0 ]; then LogText "Full string returned: ${FIND}"; fi
|
||||
RETVAL=0
|
||||
|
@ -2616,21 +2864,6 @@
|
|||
}
|
||||
|
||||
|
||||
# Show result code (to be removed)
|
||||
ShowResult() {
|
||||
case $1 in
|
||||
OK)
|
||||
echo "[ ${OK}OK${NORMAL} ]"
|
||||
;;
|
||||
WARNING)
|
||||
echo "[ ${WARNING}WARNING${NORMAL} ]"
|
||||
# log the warning to our log file
|
||||
#LogText "Warning: $2"
|
||||
# add the warning to our report file
|
||||
#Report "warning=$2"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
################################################################################
|
||||
|
@ -3191,35 +3424,44 @@
|
|||
#
|
||||
################################################################################
|
||||
# For compatibility reasons they are listed here, but will be phased out in
|
||||
# steps. If they still get used, they will trigger an alert when using the
|
||||
# developer mode. In a later phase they will trigger errors on screen.
|
||||
# steps. If they still get used, they will trigger errors on screen.
|
||||
################################################################################
|
||||
|
||||
counttests() {
|
||||
DisplayWarning "Deprecated function used (counttests)"
|
||||
if IsDeveloperMode; then Debug "Warning: old counttests function is used. Please replace any reference with CountTests."; fi
|
||||
CountTests
|
||||
}
|
||||
|
||||
logtext() {
|
||||
DisplayWarning "Deprecated function used (logtext)"
|
||||
if IsDeveloperMode; then Debug "Warning: old logtext function is used. Please replace any reference with LogText."; fi
|
||||
LogText "$1"
|
||||
}
|
||||
|
||||
logtextbreak() {
|
||||
DisplayWarning "Deprecated function used (logtextbreak)"
|
||||
if IsDeveloperMode; then Debug "Warning: old logtextbreak function is used. Please replace any reference with LogTextBreak."; fi
|
||||
LogTextBreak "$1"
|
||||
}
|
||||
|
||||
report() {
|
||||
DisplayWarning "Deprecated function used (report)"
|
||||
if IsDeveloperMode; then Debug "Warning: old report function is used. Please replace any reference with Report."; fi
|
||||
Report "$1"
|
||||
}
|
||||
|
||||
wait_for_keypress() {
|
||||
DisplayWarning "Deprecated function used (wait_for_keypress)"
|
||||
if IsDeveloperMode; then Debug "Warning: old wait_for_keypress function is used. Please replace any reference with WaitForKeyPress."; fi
|
||||
WaitForKeyPress
|
||||
}
|
||||
|
||||
ShowResult() {
|
||||
DisplayWarning "Deprecated function used (ShowResult)"
|
||||
if IsDeveloperMode; then Debug "Warning: old ShowResult() function is used. Please replace any reference with WaitForKeyPress."; fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
#================================================================================
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
#!/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 systemd-units"
|
||||
|
||||
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
|
||||
;;
|
||||
|
||||
"cronjob")
|
||||
${ECHOCMD} "Not implemented yet"
|
||||
;;
|
||||
|
||||
"systemd-units")
|
||||
|
||||
${ECHOCMD} ""
|
||||
|
||||
${ECHOCMD} "${BG_BLUE}Step 1: create service unit (/etc/systemd/system/lynis.service)${NORMAL}"
|
||||
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} "#"
|
||||
${ECHOCMD} "# Lynis service file for systemd"
|
||||
${ECHOCMD} "#"
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} "# Do not remove, so Lynis can provide a hint when a newer unit is available"
|
||||
${ECHOCMD} "# Generator=lynis"
|
||||
${ECHOCMD} "# Version=1"
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Unit]"
|
||||
${ECHOCMD} "Description=Security audit and vulnerability scanner"
|
||||
${ECHOCMD} "Documentation=https://cisofy.com/docs/"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Service]"
|
||||
${ECHOCMD} "Nice=19"
|
||||
${ECHOCMD} "IOSchedulingClass=best-effort"
|
||||
${ECHOCMD} "IOSchedulingPriority=7"
|
||||
${ECHOCMD} "Type=simple"
|
||||
MYBINARY=$(which lynis 2>/dev/null)
|
||||
MOREOPTIONS=""
|
||||
if [ -n "${LICENSE_KEY}" ]; then
|
||||
MOREOPTIONS=" --upload"
|
||||
fi
|
||||
${ECHOCMD} "ExecStart=${MYBINARY:-/path/to/lynis} audit system --cronjob${MOREOPTIONS}"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Install]"
|
||||
${ECHOCMD} "WantedBy=multi-user.target"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} ""
|
||||
|
||||
${ECHOCMD} "${BG_BLUE}Step 2: create timer unit (/etc/systemd/system/lynis.timer)${NORMAL}"
|
||||
${ECHOCMD} ""
|
||||
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} "#"
|
||||
${ECHOCMD} "# Lynis timer file for systemd"
|
||||
${ECHOCMD} "#"
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} "# Do not remove, so Lynis can provide a hint when a newer unit is available"
|
||||
${ECHOCMD} "# Generator=lynis"
|
||||
${ECHOCMD} "# Version=1"
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Unit]"
|
||||
${ECHOCMD} "Description=Daily timer for the Lynis security audit and vulnerability scanner"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Timer]"
|
||||
${ECHOCMD} "OnCalendar=daily"
|
||||
${ECHOCMD} "RandomizedDelaySec=1800"
|
||||
${ECHOCMD} "Persistent=false"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Install]"
|
||||
${ECHOCMD} "WantedBy=timers.target"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "#################################################################################"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} ""
|
||||
|
||||
${ECHOCMD} "${BG_BLUE}Step 3 - Enable the timer${NORMAL}"
|
||||
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "Tell systemd you made changes: systemctl daemon-reload"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "Enable and start the timer (so no reboot is needed): systemctl enable --now lynis.timer"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "${BG_BLUE}Optional - Customize${NORMAL}"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "Want to override the timer? Run: systemctl edit lynis.timer"
|
||||
${ECHOCMD} "Note: set the timer by first resetting it, then set the preferred value"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "[Timer]"
|
||||
${ECHOCMD} "OnCalendar="
|
||||
${ECHOCMD} "OnCalendar=*-*-* 03:00:00"
|
||||
${ECHOCMD} ""
|
||||
;;
|
||||
*) ${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
|
|
@ -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,20 @@ 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}
|
||||
|
||||
Generate systemd units to run Lynis on a schedule (e.g. daily)
|
||||
${WHITE}lynis generate systemd-units${NORMAL}
|
||||
|
||||
"
|
||||
|
||||
|
||||
UPDATE_ARGS="check info"
|
||||
UPDATE_HELP="
|
||||
${CYAN}update info${NORMAL}
|
||||
|
@ -149,15 +163,15 @@ if [ $# -gt 0 ]; then
|
|||
if [ ! -z "${CHANGELOG}" ]; then LogText "Result: found changelog file: ${CHANGELOG}"; break; fi
|
||||
done
|
||||
if [ ! -z "${CHANGELOG}" ]; then
|
||||
SEARCH=$(egrep "^${PROGRAM_NAME} ${SEARCH_VERSION}" ${CHANGELOG})
|
||||
SEARCH=$(sed 's/^## //' ${CHANGELOG} | grep -E "^${PROGRAM_NAME} ${SEARCH_VERSION}")
|
||||
if [ $? -eq 0 ]; then
|
||||
while read -r LINE; do
|
||||
if [ ${STARTED} -eq 0 ]; then
|
||||
SEARCH=$(echo ${LINE} | egrep "^${PROGRAM_NAME} ${SEARCH_VERSION}")
|
||||
SEARCH=$(echo ${LINE} | sed 's/^## //' | grep -E "^${PROGRAM_NAME} ${SEARCH_VERSION}")
|
||||
if [ $? -eq 0 ]; then STARTED=1; ${ECHOCMD} "${BOLD}${LINE}${NORMAL}"; fi
|
||||
else
|
||||
# Stop if we find the next Lynis version
|
||||
SEARCH=$(echo ${LINE} | egrep "^${PROGRAM_NAME} [0-9]\.[0-9]\.[0-9]")
|
||||
SEARCH=$(echo ${LINE} | sed 's/^## //' | grep -E "^${PROGRAM_NAME} [0-9]\.[0-9]\.[0-9]")
|
||||
if [ $? -eq 0 ]; then
|
||||
break
|
||||
else
|
||||
|
@ -172,7 +186,7 @@ if [ $# -gt 0 ]; then
|
|||
${ECHOCMD} "$0 lynis show changelog [version]"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "${HEADER}${PROGRAM_NAME} versions:${NORMAL}"
|
||||
SEARCH=$(egrep "^Lynis [0-9]\.[0-9]\.[0-9] " ${CHANGELOG} | awk '{print $2}' | sort -n)
|
||||
SEARCH=$(sed 's/^## //' ${CHANGELOG} | grep -E "^Lynis [0-9]\.[0-9]\.[0-9] " | awk '{print $2}' | sort -n)
|
||||
${ECHOCMD} ${SEARCH}
|
||||
ExitFatal
|
||||
fi
|
||||
|
@ -274,6 +288,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}" ;;
|
||||
|
|
|
@ -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" ;;
|
||||
|
|
|
@ -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
|
||||
|
@ -201,7 +233,7 @@
|
|||
# Cronjob support
|
||||
--cron-job | --cronjob | --cron)
|
||||
CRONJOB=1
|
||||
CHECK=1; QUICKMODE=1; COLORS=0; NEVERBREAK=1 # Use some defaults (-c, -Q, no colors)
|
||||
CHECK=1; COLORS=0; NEVERBREAK=1 # Use some defaults ('audit system', -Q, no colors)
|
||||
RemoveColors
|
||||
;;
|
||||
|
||||
|
@ -313,7 +345,6 @@
|
|||
# Quiet mode
|
||||
--quiet | -q | --silent)
|
||||
QUIET=1
|
||||
QUICKMODE=1 # Run non-interactive
|
||||
;;
|
||||
|
||||
# Non-interactive mode
|
||||
|
@ -412,7 +443,6 @@
|
|||
# Warnings
|
||||
--warnings-only | --show-warnings-only)
|
||||
SHOW_WARNINGS_ONLY=1
|
||||
QUICKMODE=1
|
||||
QUIET=1
|
||||
;;
|
||||
|
||||
|
@ -433,5 +463,15 @@
|
|||
|
||||
done
|
||||
|
||||
# Ensure non-interactive mode when running quietly or as cronjob
|
||||
if [ ${CRONJOB} -eq 1 -o ${QUIET} -eq 1 ]; then
|
||||
if [ ${QUICKMODE} -eq 0 ]; then
|
||||
if [ ${QUIET} -eq 0 ]; then
|
||||
echo "Switched back to quick mode (cron/non-interactive/quiet)"
|
||||
fi
|
||||
QUICKMODE=1
|
||||
fi
|
||||
fi
|
||||
|
||||
#================================================================================
|
||||
# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com
|
||||
|
|
|
@ -32,9 +32,38 @@
|
|||
for PROFILE in ${PROFILES}; do
|
||||
|
||||
LogText "Reading profile/configuration ${PROFILE}"
|
||||
FIND=$(egrep "^config:|^[a-z-].*=" ${PROFILE} | sed 's/ /!space!/g')
|
||||
for CONFIGOPTION in ${FIND}; do
|
||||
if ContainsString "config:" "${CONFIGOPTION}"; then
|
||||
|
||||
# Show deprecation message for old config entries
|
||||
FOUND=0
|
||||
#DATA=$(egrep "^config:" ${PROFILE} | od --address-radix=none -t a | sed 's/ /!space!/g')
|
||||
#if ! IsEmpty "${DATA}"; then FOUND=1; fi
|
||||
# Items such as 'apache:'
|
||||
DATA=$(egrep "^[a-z-]{1,}:" ${PROFILE} | od --address-radix=none -t a | sed 's/ /!space!/g')
|
||||
if ! IsEmpty "${DATA}"; then FOUND=1; fi
|
||||
|
||||
if [ ${FOUND} -eq 1 ]; then
|
||||
DisplayWarning "Your profile contains old-style configuration entries. See log file for more details and how to convert these entries"
|
||||
LogText "Your profile has one or more configuration items that are in an old format (lines starting with key:value). They need to be converted into the new format (key=value)."
|
||||
LogText "Tip: Use egrep to see the relevant matches (egrep \"^[a-z-]{1,}:\" custom.prf)"
|
||||
sleep 30
|
||||
fi
|
||||
|
||||
# Security check for unexpected and possibly harmful escape characters
|
||||
DATA=$(grep -v '^$\|^ \|^#\|^config:' ${PROFILE} | tr -d '[:alnum:]/\[\]\(\)\-_\|,\.:;= \n\r' | od --address-radix=none -t a | sed 's/ /!space!/g')
|
||||
if ! IsEmpty "${DATA}"; then
|
||||
DisplayWarning "Your profile '${PROFILE}' contains unexpected characters. See the log file for more information."
|
||||
LogText "Found unexpected or possibly harmful characters in the profile. See output below."
|
||||
for I in "${DATA}"; do
|
||||
I=$(echo ${I} | sed 's/!space!/ /g')
|
||||
LogText "Output: ${I}"
|
||||
done
|
||||
sleep 30
|
||||
fi
|
||||
|
||||
# Now parse the profile and filter out unwanted characters
|
||||
DATA=$(egrep "^config:|^[a-z-].*=" ${PROFILE} | tr -dc '[:alnum:]/\[\]\(\)\-_\|,\.:;= \n\r' | sed 's/ /!space!/g')
|
||||
for CONFIGOPTION in ${DATA}; do
|
||||
if ContainsString "^config:" "${CONFIGOPTION}"; then
|
||||
# Old style configuration
|
||||
OPTION=$(echo ${CONFIGOPTION} | cut -d ':' -f2)
|
||||
VALUE=$(echo ${CONFIGOPTION} | cut -d ':' -f3 | sed 's/!space!/ /g')
|
||||
|
@ -90,7 +119,7 @@
|
|||
;;
|
||||
|
||||
# Ignore configuration data
|
||||
config-data)
|
||||
config-data | permdir | permfile)
|
||||
Debug "Ignoring configuration option, as it will be used by a specific test"
|
||||
;;
|
||||
|
||||
|
@ -239,6 +268,11 @@
|
|||
LogText "Plugin '${VALUE}' enabled according profile (${PROFILE})"
|
||||
;;
|
||||
|
||||
disable-plugin)
|
||||
LogText "Plugin '${VALUE}' disabled according profile (${PROFILE})"
|
||||
DISABLED_PLUGINS="${DISABLED_PLUGINS} ${VALUE}"
|
||||
;;
|
||||
|
||||
# Plugin directory
|
||||
plugindir | plugin-dir)
|
||||
if IsEmpty "${PLUGINDIR}"; then
|
||||
|
@ -256,9 +290,9 @@
|
|||
|
||||
# Quick (no waiting for keypresses)
|
||||
quick)
|
||||
# Quick mode (SKIP_PLUGINS) might already be set outside profile, so store in different variable
|
||||
SETTING_QUICK_MODE=0 # default is no
|
||||
FIND=$(echo "${VALUE}" | egrep "^(1|true|yes)$") && QUICKMODE=1
|
||||
# Quick mode might already be set outside profile, so store in different variable
|
||||
SETTING_QUICK_MODE=1 # default is yes
|
||||
FIND=$(echo "${VALUE}" | egrep "^(0|false|no)$") && QUICKMODE=0
|
||||
if [ ! -z "${FIND}" ]; then SETTING_QUICK_MODE=1; fi
|
||||
Debug "Quickmode set to ${SETTING_QUICK_MODE}"
|
||||
AddSetting "quick" "${SETTING_QUICK_MODE}" "Quick mode (non-interactive)"
|
||||
|
@ -328,6 +362,13 @@
|
|||
AddSetting "ssl-certificate-paths" "${SSL_CERTIFICATE_PATHS}" "Paths for SSL certificates"
|
||||
;;
|
||||
|
||||
ssl-certificate-paths-to-ignore)
|
||||
# Retrieve paths to ignore when searching for certificates. Strip special characters, replace possible spaces
|
||||
SSL_CERTIFICATE_PATHS_TO_IGNORE=$(echo ${VALUE} | tr -d '[:cntrl:]' | sed 's/ /__space__/g' | tr ':' ' ')
|
||||
Debug "SSL paths to ignore: ${SSL_CERTIFICATE_PATHS_TO_IGNORE}"
|
||||
AddSetting "ssl-certificate-paths-to-ignore" "${SSL_CERTIFICATE_PATHS_TO_IGNORE}" "Paths that should be ignored for SSL certificates"
|
||||
;;
|
||||
|
||||
# Set strict mode for development and quality purposes
|
||||
strict)
|
||||
FIND=$(echo "${VALUE}" | egrep "^(1|true|yes)") && SET_STRICT=1
|
||||
|
@ -441,10 +482,14 @@
|
|||
# Catch all bad options and bail out
|
||||
*)
|
||||
LogText "Unknown option ${OPTION} (with value: ${VALUE})"
|
||||
${ECHOCMD} ""
|
||||
${ECHOCMD} "${RED}Error${NORMAL}: found one or more errors in profile ${PROFILE}"
|
||||
${ECHOCMD} "${WHITE}Details${NORMAL}: Unknown option '${YELLOW}${OPTION}${NORMAL}' found (with value: ${VALUE})"
|
||||
${ECHOCMD} ""
|
||||
|
||||
${ECHOCMD:-echo} ""
|
||||
${ECHOCMD:-echo} "${RED}Error${NORMAL}: found one or more errors in profile ${PROFILE}"
|
||||
${ECHOCMD:-echo} ""
|
||||
${ECHOCMD:-echo} ""
|
||||
${ECHOCMD:-echo} "Full line: ${CONFIGOPTION}"
|
||||
${ECHOCMD:-echo} "${WHITE}Details${NORMAL}: Unknown option '${YELLOW}${OPTION}${NORMAL}' found (with value: ${VALUE})"
|
||||
${ECHOCMD:-echo} ""
|
||||
ExitFatal
|
||||
;;
|
||||
|
||||
|
|
114
include/report
114
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.
|
||||
|
||||
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
|
||||
# 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
|
||||
|
||||
HPGRAPH="[${HPCOLOR}${HPBLOCKS}${NORMAL}${HPEMPTY}]"
|
||||
LogText "Hardening index : [${HPINDEX}] [${HPBLOCKS}${HPEMPTY}]"
|
||||
LogText "Hardening strength: ${HIDESCRIPTION}"
|
||||
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}"
|
||||
|
||||
|
||||
# Only show overview if not running in quiet mode
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -34,55 +34,78 @@
|
|||
COUNT_EXPIRED=0
|
||||
COUNT_TOTAL=0
|
||||
FOUNDPROBLEM=0
|
||||
sSSL_PATHS=$(echo ${SSL_CERTIFICATE_PATHS} | ${SEDBINARY} 's/:/ /g')
|
||||
sSSL_PATHS=$(echo ${sSSL_PATHS} | ${SEDBINARY} 's/^ //' | ${TRBINARY} " " "\n" | ${SORTBINARY} | uniq | ${TRBINARY} "\n" " ")
|
||||
SKIP=0
|
||||
sSSL_PATHS=$(echo ${SSL_CERTIFICATE_PATHS} | ${SEDBINARY} 's/:space:/__space__/g' | ${SEDBINARY} 's/:/ /g')
|
||||
sSSL_PATHS=$(echo ${sSSL_PATHS} | ${SEDBINARY} 's/^ //' | ${SORTBINARY} | ${UNIQBINARY})
|
||||
LogText "Paths to scan: ${sSSL_PATHS}"
|
||||
|
||||
IGNORE_PATHS_PRINT=$(echo ${SSL_CERTIFICATE_PATHS_TO_IGNORE} | ${SEDBINARY} 's/:/, /g' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/^ //' | ${SORTBINARY} | ${UNIQBINARY})
|
||||
LogText "Paths to ignore: ${IGNORE_PATHS_PRINT}"
|
||||
|
||||
for DIR in ${sSSL_PATHS}; do
|
||||
COUNT_DIR=0
|
||||
if [ -d ${DIR} ]; then
|
||||
FileIsReadable ${DIR}
|
||||
if [ ${CANREAD} -eq 1 ]; then
|
||||
LASTSUBDIR=""
|
||||
LogText "Result: found directory ${DIR}"
|
||||
# Search for certificate files
|
||||
FILES=$(${FINDBINARY} ${DIR} -type f 2> /dev/null | ${EGREPBINARY} ".crt$|.pem$|^cert" | ${SORTBINARY} | ${SEDBINARY} 's/ /:space:/g')
|
||||
FILES=$(${FINDBINARY} ${DIR} -type f 2> /dev/null | ${EGREPBINARY} ".crt$|.pem$|^cert" | ${SORTBINARY} | ${SEDBINARY} 's/ /__space__/g')
|
||||
for FILE in ${FILES}; do
|
||||
FILE=$(echo ${FILE} |${SEDBINARY} 's/:space:/ /g')
|
||||
COUNT_DIR=$((COUNT_DIR + 1))
|
||||
FileIsReadable "${FILE}"
|
||||
if [ ${CANREAD} -eq 1 ]; then
|
||||
# Only check the files that are not installed by a package
|
||||
if ! FileInstalledByPackage "${FILE}"; then
|
||||
LogText "Test: test if file is a certificate"
|
||||
OUTPUT=$(${GREPBINARY} -q 'BEGIN CERT' "${FILE}")
|
||||
if [ $? -eq 0 ]; then
|
||||
LogText "Result: file is a certificate"
|
||||
LogText "Test: checking certificate details"
|
||||
FIND=$(${OPENSSLBINARY} x509 -noout -in "${FILE}" -enddate 2> /dev/null | ${GREPBINARY} "^notAfter")
|
||||
FILE=$(echo ${FILE} | ${SEDBINARY} 's/__space__/ /g')
|
||||
# See if we need to skip this path
|
||||
SUBDIR=$(echo ${FILE} | ${AWKBINARY} -F/ 'sub(FS $NF,x)' | ${SEDBINARY} 's/__space__/ /g')
|
||||
# If we discover a new directory, do evaluation
|
||||
#Debug "File : ${FILE}"
|
||||
#Debug "Lastdir: ${LASTSUBDIR}"
|
||||
#Debug "Curdir : ${SUBDIR}"
|
||||
if [ ! "${SUBDIR}" = "${LASTSUBDIR}" ]; then
|
||||
SKIP=0
|
||||
# Now check if this path is on the to-be-ignored list
|
||||
for D in ${SSL_CERTIFICATE_PATHS_TO_IGNORE}; do
|
||||
if Equals "${D}" "${SUBDIR}"; then
|
||||
SKIP=1
|
||||
LogText "Result: skipping directory (${SUBDIR}) as it is on ignore list"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [ ${SKIP} -eq 0 ]; then
|
||||
#Debug "Testing ${FILE} in path: $SUBDIR"
|
||||
COUNT_DIR=$((COUNT_DIR + 1))
|
||||
FileIsReadable "${FILE}"
|
||||
if [ ${CANREAD} -eq 1 ]; then
|
||||
# Only check the files that are not installed by a package
|
||||
if ! FileInstalledByPackage "${FILE}"; then
|
||||
OUTPUT=$(${GREPBINARY} -q 'BEGIN CERT' "${FILE}")
|
||||
if [ $? -eq 0 ]; then
|
||||
# Check certificate where 'end date' has been expired
|
||||
FIND=$(${OPENSSLBINARY} x509 -noout -checkend 0 -in "${FILE}" -enddate 2> /dev/null)
|
||||
EXIT_CODE=$?
|
||||
CERT_CN=$(${OPENSSLBINARY} x509 -noout -subject -in "${FILE}" 2> /dev/null | ${SEDBINARY} -e 's/^subject.*CN=\([a-zA-Z0-9\.\-\*]*\).*$/\1/')
|
||||
CERT_NOTAFTER=$(${OPENSSLBINARY} x509 -noout -enddate -in "${FILE}" 2> /dev/null | ${AWKBINARY} -F= '{if ($1=="notAfter") { print $2 }}')
|
||||
Report "certificate[]=${FILE}|${EXIT_CODE}|cn:${CERT_CN};notafter:${CERT_NOTAFTER};|"
|
||||
if [ ${EXIT_CODE} -eq 0 ]; then
|
||||
LogText "Result: certificate ${FILE} seems to be correct and still valid"
|
||||
LogText "Result: file is a certificate file"
|
||||
FIND=$(${OPENSSLBINARY} x509 -noout -in "${FILE}" -enddate 2> /dev/null | ${GREPBINARY} "^notAfter")
|
||||
if [ $? -eq 0 ]; then
|
||||
# Check certificate where 'end date' has been expired
|
||||
FIND=$(${OPENSSLBINARY} x509 -noout -checkend 0 -in "${FILE}" -enddate 2> /dev/null)
|
||||
EXIT_CODE=$?
|
||||
CERT_CN=$(${OPENSSLBINARY} x509 -noout -subject -in "${FILE}" 2> /dev/null | ${SEDBINARY} -e 's/^subject.*CN=\([a-zA-Z0-9\.\-\*]*\).*$/\1/')
|
||||
CERT_NOTAFTER=$(${OPENSSLBINARY} x509 -noout -enddate -in "${FILE}" 2> /dev/null | ${AWKBINARY} -F= '{if ($1=="notAfter") { print $2 }}')
|
||||
Report "certificate[]=${FILE}|${EXIT_CODE}|cn:${CERT_CN};notafter:${CERT_NOTAFTER};|"
|
||||
if [ ${EXIT_CODE} -eq 0 ]; then
|
||||
LogText "Result: certificate ${FILE} seems to be correct and still valid"
|
||||
else
|
||||
FOUNDPROBLEM=1
|
||||
COUNT_EXPIRED=$((COUNT_EXPIRED + 1))
|
||||
LogText "Result: certificate ${FILE} has been expired"
|
||||
fi
|
||||
else
|
||||
FOUNDPROBLEM=1
|
||||
COUNT_EXPIRED=$((COUNT_EXPIRED + 1))
|
||||
LogText "Result: certificate ${FILE} has been expired"
|
||||
LogText "Result: skipping tests for this file (${FILE}) as it is most likely not a certificate (is it a key file?)"
|
||||
fi
|
||||
else
|
||||
LogText "Result: skipping tests for this file (${FILE}) as it is most likely not a certificate (a key file?)"
|
||||
LogText "Result: skipping test for this file (${FILE}) as we could not find 'BEGIN CERT'"
|
||||
fi
|
||||
else
|
||||
LogText "Result: skipping test for this file (${FILE}) as we could not find 'BEGIN CERT'"
|
||||
fi
|
||||
else
|
||||
LogText "Result: can not read file ${FILE} (no permission)"
|
||||
fi
|
||||
else
|
||||
LogText "Result: can not read file ${FILE} (no permission)"
|
||||
fi
|
||||
LASTSUBDIR="${SUBDIR}"
|
||||
done
|
||||
COUNT_TOTAL=$((COUNT_TOTAL + COUNT_DIR))
|
||||
LogText "Result: found ${COUNT_DIR} certificates in ${DIR}"
|
||||
|
@ -105,6 +128,30 @@
|
|||
fi
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
# Test : CRYP-7930
|
||||
# Description : Determine if system uses disk or file encryption
|
||||
Register --test-no CRYP-7930 --weight L --network NO --category security --description "Determine if system uses disk or file encryption"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
FILE="${ROOTDIR}etc/crypttab"
|
||||
if [ -f ${FILE} ]; then
|
||||
LogText "Result: crypttab file (${FILE}) exists"
|
||||
DATA=$(${GREPBINARY} "^[a-z]" ${FILE} | ${TRBINARY} -cd '[:alnum:]_\-=,\n\t ' | ${SEDBINARY} 's/[[:blank:]]/__space__/g')
|
||||
for LINE in ${DATA}; do
|
||||
LINE=$(echo ${LINE} | ${SEDBINARY} 's/__space__/ /g')
|
||||
if ContainsString "luks," "${LINE}"; then
|
||||
PARTITION=$(echo ${LINE} | ${AWKBINARY} '{print $1}' | ${AWKBINARY} -F_ '{print $1}')
|
||||
LogText "Result: Found LUKS encryption on partition ${PARTITION}"
|
||||
Report "encryption[]=luks,partition,${PARTITION}"
|
||||
fi
|
||||
done
|
||||
unset DATA LINE PARTITION
|
||||
else
|
||||
LogText "Result: crypttab file (${FILE}) does not exist"
|
||||
fi
|
||||
fi
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
|
||||
WaitForKeyPress
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
LogText "Test: Checking file permissions"
|
||||
for PROFILE in ${PROFILES}; do
|
||||
LogText "Using profile ${PROFILE} for baseline."
|
||||
FIND=$(${EGREPBINARY} '^permfile:|^permdir:' ${PROFILE} | ${CUTBINARY} -d: -f2)
|
||||
FIND=$(${EGREPBINARY} '^permfile=|^permdir=' ${PROFILE} | ${CUTBINARY} -d= -f2)
|
||||
for I in ${FIND}; do
|
||||
LogText "Checking ${I}"
|
||||
CheckFilePermissions ${I}
|
||||
CheckFilePermissions "${I}"
|
||||
LogText " Expected permissions: ${PROFILEVALUE}"
|
||||
LogText " Actual permissions: ${FILEVALUE}"
|
||||
LogText " Result: $PERMS"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
@ -108,6 +131,289 @@
|
|||
fi
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
# 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"
|
||||
|
|
|
@ -30,17 +30,17 @@
|
|||
# Description : Query /proc/meminfo
|
||||
Register --test-no PROC-3602 --os Linux --weight L --network NO --category security --description "Checking /proc/meminfo for memory details"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
if [ -f /proc/meminfo ]; then
|
||||
LogText "Result: found /proc/meminfo"
|
||||
Display --indent 2 --text "- Checking /proc/meminfo" --result "${STATUS_FOUND}" --color GREEN
|
||||
FIND=$(${AWKBINARY} '/^MemTotal/ { print $2, $3 }' /proc/meminfo)
|
||||
if [ -f ${ROOTDIR}proc/meminfo ]; then
|
||||
LogText "Result: found ${ROOTDIR}proc/meminfo"
|
||||
Display --indent 2 --text "- Checking ${ROOTDIR}proc/meminfo" --result "${STATUS_FOUND}" --color GREEN
|
||||
FIND=$(${AWKBINARY} '/^MemTotal/ { print $2, $3 }' ${ROOTDIR}proc/meminfo)
|
||||
MEMORY_SIZE=$(echo ${FIND} | ${AWKBINARY} '{ print $1 }')
|
||||
MEMORY_UNITS=$(echo ${FIND} | ${AWKBINARY} '{ print $2 }')
|
||||
LogText "Result: Found ${MEMORY_SIZE} ${MEMORY_UNITS} memory"
|
||||
Report "memory_size=${MEMORY_SIZE}"
|
||||
Report "memory_units=${MEMORY_UNITS}"
|
||||
else
|
||||
LogText "Result: /proc/meminfo file not found on this system"
|
||||
LogText "Result: ${ROOTDIR}proc/meminfo file not found on this system"
|
||||
fi
|
||||
fi
|
||||
#
|
||||
|
@ -80,7 +80,7 @@
|
|||
fi
|
||||
if [ -z "${FIND}" ]; then
|
||||
LogText "Result: no zombie processes found"
|
||||
Display --indent 2 --text "- Searching for dead/zombie processes" --result "${STATUS_OK}" --color GREEN
|
||||
Display --indent 2 --text "- Searching for dead/zombie processes" --result "${STATUS_NOT_FOUND}" --color GREEN
|
||||
else
|
||||
LogText "Result: found one or more dead or zombie processes"
|
||||
LogText "Output: PIDs ${FIND}"
|
||||
|
@ -104,7 +104,7 @@
|
|||
fi
|
||||
if [ -z "${FIND}" ]; then
|
||||
LogText "Result: No processes were waiting for IO requests to be handled first"
|
||||
Display --indent 2 --text "- Searching for IO waiting processes" --result "${STATUS_OK}" --color GREEN
|
||||
Display --indent 2 --text "- Searching for IO waiting processes" --result "${STATUS_NOT_FOUND}" --color GREEN
|
||||
else
|
||||
LogText "Result: found one or more processes which were waiting to get IO requests handled first"
|
||||
LogText "More info: processes which show up with the status flag 'D' are often stuck, until a disk IO event finished. This can happen for example with network storage, where the connection or protocol settings are not logtext well configured."
|
||||
|
@ -116,6 +116,27 @@
|
|||
#
|
||||
#################################################################################
|
||||
#
|
||||
# Test : PROC-3802
|
||||
# Description : Check presence of prelink tooling
|
||||
Register --test-no PROC-3802 --weight L --network NO --category security --description "Check presence of prelink tooling"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
if PackageIsInstalled "prelink"; then
|
||||
LogText "Result: prelink packages is installed"
|
||||
# TODO
|
||||
# - Add item to website with rationale
|
||||
#ReportSuggestion "${TEST_NO}" "Disable and remove prelinking of binaries"
|
||||
AddHP 1 3
|
||||
Display --indent 2 --text "- Search prelink tooling" --result "${STATUS_FOUND}" --color YELLOW
|
||||
else
|
||||
Display --indent 2 --text "- Search prelink tooling" --result "${STATUS_NOT_FOUND}" --color GREEN
|
||||
LogText "Result: prelink package is NOT installed"
|
||||
AddHP 3 3
|
||||
fi
|
||||
fi
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
|
||||
|
||||
WaitForKeyPress
|
||||
|
||||
|
|
|
@ -644,15 +644,15 @@
|
|||
if [ "${FIND}" = "127.0.0.1" ]; then
|
||||
LogText "Result: localhost mapped to 127.0.0.1"
|
||||
Display --indent 4 --text "- Checking /etc/hosts (localhost to IP)" --result "${STATUS_OK}" --color GREEN
|
||||
report "localhost-mapped-to=${FIND}"
|
||||
Report "localhost-mapped-to=${FIND}"
|
||||
elif [ "${FIND}" = "::1" ]; then
|
||||
LogText "Result: localhost mapped to ::1"
|
||||
Display --indent 4 --text "- Checking /etc/hosts (localhost to IP)" --result "${STATUS_OK}" --color GREEN
|
||||
report "localhost-mapped-to=${FIND}"
|
||||
Report "localhost-mapped-to=${FIND}"
|
||||
elif [ "${FIND}" = "127.0.0.1::1" ]; then
|
||||
LogText "Result: localhost mapped to 127.0.0.1 and ::1"
|
||||
Display --indent 4 --text "- Checking /etc/hosts (localhost to IP)" --result "${STATUS_OK}" --color GREEN
|
||||
report "localhost-mapped-to=${FIND}"
|
||||
Report "localhost-mapped-to=${FIND}"
|
||||
else
|
||||
LogText "Output: ${FIND}"
|
||||
LogText "Result: this server hostname is not mapped to a local address"
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
@ -610,33 +610,34 @@
|
|||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
FOUND=0
|
||||
|
||||
# addrwatch
|
||||
if IsRunning "addrwatch"; then
|
||||
FOUND=1
|
||||
fi
|
||||
|
||||
# arpwatch
|
||||
IsRunning arpwatch
|
||||
if [ ${RUNNING} -eq 1 ]; then
|
||||
if IsRunning "arpwatch"; then
|
||||
FOUND=1
|
||||
ARPWATCH_RUNNING=1
|
||||
Display --indent 2 --text "- Checking for ARP monitoring software" --result "${STATUS_RUNNING}" --color GREEN
|
||||
fi
|
||||
|
||||
# arpon
|
||||
IsRunning arpon
|
||||
if [ ${RUNNING} -eq 1 ]; then
|
||||
if IsRunning "arpon"; then
|
||||
FOUND=1
|
||||
ARPON_RUNNING=1
|
||||
Display --indent 2 --text "- Checking for ARP monitoring software" --result "${STATUS_RUNNING}" --color GREEN
|
||||
fi
|
||||
if [ ${FOUND} -eq 0 ]; then
|
||||
|
||||
if [ ${FOUND} -eq 1 ]; then
|
||||
Display --indent 2 --text "- Checking for ARP monitoring software" --result "${STATUS_RUNNING}" --color GREEN
|
||||
else
|
||||
Display --indent 2 --text "- Checking for ARP monitoring software" --result "${STATUS_NOT_FOUND}" --color YELLOW
|
||||
ReportSuggestion ${TEST_NO} "Consider running ARP monitoring software (arpwatch,arpon)"
|
||||
ReportSuggestion "${TEST_NO}" "Consider running ARP monitoring software (addrwatch,arpwatch,arpon)"
|
||||
fi
|
||||
fi
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
|
||||
Report "dhcp_client_running=${DHCP_CLIENT_RUNNING}"
|
||||
Report "arpwatch_running=${ARPWATCH_RUNNING}"
|
||||
|
||||
WaitForKeyPress
|
||||
|
||||
#
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
@ -879,8 +879,7 @@
|
|||
if [ ${DO_TEST} -eq 0 ]; then
|
||||
FileExists ${ROOTDIR}usr/share/yum-cli/cli.py
|
||||
if [ ${FILE_FOUND} -eq 1 ]; then
|
||||
SearchItem "\-\-security" "${ROOTDIR}usr/share/yum-cli/cli.py"
|
||||
if [ ${ITEM_FOUND} -eq 1 ]; then
|
||||
if SearchItem "\-\-security" "${ROOTDIR}usr/share/yum-cli/cli.py"; then
|
||||
DO_TEST=1
|
||||
LogText "Result: found built-in security in yum"
|
||||
else
|
||||
|
@ -892,8 +891,7 @@
|
|||
if [ ${DO_TEST} -eq 0 ]; then
|
||||
FileExists ${ROOTDIR}etc/yum/pluginconf.d/security.conf
|
||||
if [ ${FILE_FOUND} -eq 1 ]; then
|
||||
SearchItem "^enabled=1$" "${ROOTDIR}etc/yum/pluginconf.d/security.conf"
|
||||
if [ ${ITEM_FOUND} -eq 1 ]; then
|
||||
if SearchItem "^enabled=1$" "${ROOTDIR}etc/yum/pluginconf.d/security.conf"; then
|
||||
DO_TEST=1
|
||||
LogText "Result: found enabled plugin"
|
||||
else
|
||||
|
@ -930,7 +928,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"
|
||||
|
@ -968,8 +965,8 @@
|
|||
FOUND=0
|
||||
FileExists ${ROOTDIR}etc/yum.conf
|
||||
if [ ${FILE_FOUND} -eq 1 ]; then
|
||||
SearchItem "^gpgenabled\s*=\s*1$" "${ROOTDIR}etc/yum.conf"; if [ ${ITEM_FOUND} -eq 1 ]; then FOUND=1; fi
|
||||
SearchItem "^gpgcheck\s*=\s*1$" "${ROOTDIR}etc/yum.conf"; if [ ${ITEM_FOUND} -eq 1 ]; then FOUND=1; fi
|
||||
if SearchItem "^gpgenabled\s*=\s*1$" "${ROOTDIR}etc/yum.conf"; then FOUND=1; fi
|
||||
if SearchItem "^gpgcheck\s*=\s*1$" "${ROOTDIR}etc/yum.conf"; then FOUND=1; fi
|
||||
if [ ${FOUND} -eq 1 ]; then
|
||||
LogText "Result: GPG check is enabled"
|
||||
Display --indent 2 --text "- Checking GPG checks (yum.conf)" --result "${STATUS_OK}" --color GREEN
|
||||
|
@ -1055,7 +1052,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 +1245,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 +1266,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
|
||||
|
||||
if [ ! -z "${INSTALLED_PACKAGES}" ]; then Report "installed_packages_array=${INSTALLED_PACKAGES}"; fi
|
||||
case "${OS}" in
|
||||
"Linux")
|
||||
case "${LINUX_VERSION}" in
|
||||
"CentOS" | "Debian" | "Fedora" | "RHEL" | "Ubuntu")
|
||||
|
||||
Report "package_audit_tool=${PACKAGE_AUDIT_TOOL}"
|
||||
Report "package_audit_tool_found=${PACKAGE_AUDIT_TOOL_FOUND}"
|
||||
Report "vulnerable_packages_found=${VULNERABLE_PACKAGES_FOUND}"
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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=""
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
SSH_DAEMON_PORT=""
|
||||
SSH_DAEMON_RUNNING=0
|
||||
SSH_DAEMON_OPTIONS_FILE=""
|
||||
OPENSSHD_RUNNING=0
|
||||
OPENSSHD_VERSION=0
|
||||
OPENSSHD_VERSION_MAJOR=0
|
||||
OPENSSHD_VERSION_MINOR=0
|
||||
|
@ -42,8 +43,8 @@
|
|||
Register --test-no SSH-7402 --weight L --network NO --category security --description "Check for running SSH daemon"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
LogText "Test: Searching for a SSH daemon"
|
||||
IsRunning sshd
|
||||
if [ ${RUNNING} -eq 1 ] || PortIsListening "TCP" 22; then
|
||||
if IsRunning "sshd"; then
|
||||
OPENSSHD_RUNNING=1
|
||||
SSH_DAEMON_RUNNING=1
|
||||
Display --indent 2 --text "- Checking running SSH daemon" --result "${STATUS_FOUND}" --color GREEN
|
||||
# Store settings in a temporary file
|
||||
|
@ -51,6 +52,9 @@
|
|||
SSH_DAEMON_OPTIONS_FILE="${TEMP_FILE}"
|
||||
# Use a non-existing user, to ensure that systems that have a Match block configured, will be evaluated as well
|
||||
${SSHDBINARY} -T -C user=doesnotexist,host=none,addr=none 2> /dev/null > ${SSH_DAEMON_OPTIONS_FILE}
|
||||
elif PortIsListening "TCP" 22; then
|
||||
Display --indent 2 --text "- Checking running SSH daemon" --result "${STATUS_FOUND}" --color GREEN
|
||||
SSH_DAEMON_RUNNING=1
|
||||
else
|
||||
Display --indent 2 --text "- Checking running SSH daemon" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
fi
|
||||
|
@ -60,7 +64,7 @@
|
|||
#
|
||||
# Test : SSH-7404
|
||||
# Description : Determine SSH daemon configuration file location
|
||||
if [ ${SSH_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
if [ ${OPENSSHD_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
Register --test-no SSH-7404 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check SSH daemon file location"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
FOUND=0
|
||||
|
@ -95,7 +99,7 @@
|
|||
#
|
||||
# Test : SSH-7406
|
||||
# Description : Check OpenSSH version
|
||||
if [ ${SSH_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
if [ ${OPENSSHD_RUNNING} -eq 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
Register --test-no SSH-7406 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Determine OpenSSH version"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
OPENSSHD_VERSION=$(${SSHDBINARY} -t -d 2>&1 | ${GREPBINARY} 'sshd version' | ${AWKBINARY} '{if($4~OpenSSH_){print $4}}' | ${AWKBINARY} -F_ '{print $2}' | ${TRBINARY} -d ',' | ${TRBINARY} -d '\r')
|
||||
|
@ -113,7 +117,7 @@
|
|||
# Test : SSH-7408
|
||||
# Description : Check SSH specific defined options
|
||||
# Notes : Instead of parsing the configuration file, we query the SSH daemon itself
|
||||
if [ ${SSH_DAEMON_RUNNING} -eq 1 -a ! -z "${SSH_DAEMON_OPTIONS_FILE}" -a ${OPENSSHD_VERSION_MAJOR} -ge 5 -a ${OPENSSHD_VERSION_MINOR} -ge 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
if [ ${OPENSSHD_RUNNING} -eq 1 -a ! -z "${SSH_DAEMON_OPTIONS_FILE}" -a ${OPENSSHD_VERSION_MAJOR} -ge 5 -a ${OPENSSHD_VERSION_MINOR} -ge 1 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
Register --test-no SSH-7408 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check SSH specific defined options"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
LogText "Test: Checking specific defined options in ${SSH_DAEMON_OPTIONS_FILE}"
|
||||
|
@ -258,31 +262,31 @@
|
|||
fi
|
||||
|
||||
if [ "${RESULT}" = "GOOD" ]; then
|
||||
LogText "Result: SSH option ${OPTIONNAME} is configured very well"
|
||||
Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result "${STATUS_OK}" --color GREEN
|
||||
LogText "Result: OpenSSH option ${OPTIONNAME} is configured very well"
|
||||
Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_OK}" --color GREEN
|
||||
AddHP 3 3
|
||||
elif [ "${RESULT}" = "MIDSCORED" ]; then
|
||||
LogText "Result: SSH option ${OPTIONNAME} is configured reasonably"
|
||||
LogText "Result: OpenSSH option ${OPTIONNAME} is configured reasonably"
|
||||
ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (${FOUNDVALUE} --> ${EXPECTEDVALUE})" "-"
|
||||
ReportDetails --test "${TEST_NO}" --service "sshd" --field "${OPTIONNAME}" --value "${FOUNDVALUE}" --preferredvalue "${EXPECTEDVALUE}" --description "sshd option ${OPTIONNAME}"
|
||||
Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW
|
||||
Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW
|
||||
AddHP 1 3
|
||||
elif [ "${RESULT}" = "WEAK" ]; then
|
||||
LogText "Result: SSH option ${OPTIONNAME} is in a weak configuration state and should be fixed"
|
||||
LogText "Result: OpenSSH option ${OPTIONNAME} is in a weak configuration state and should be fixed"
|
||||
ReportSuggestion ${TEST_NO} "Consider hardening SSH configuration" "${OPTIONNAME} (${FOUNDVALUE} --> ${EXPECTEDVALUE})" "-"
|
||||
ReportDetails --test "${TEST_NO}" --service "sshd" --field "${OPTIONNAME}" --value "${FOUNDVALUE}" --preferredvalue "${EXPECTEDVALUE}" --description "sshd option ${OPTIONNAME}"
|
||||
Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW
|
||||
Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_SUGGESTION}" --color YELLOW
|
||||
AddHP 0 3
|
||||
elif [ "${RESULT}" = "UNKNOWN" ]; then
|
||||
LogText "Result: Value of SSH option ${OPTIONNAME} is unknown (not defined)"
|
||||
Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result DEFAULT --color WHITE
|
||||
LogText "Result: Value of OpenSSH option ${OPTIONNAME} is unknown (not defined)"
|
||||
Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result DEFAULT --color WHITE
|
||||
Report "unknown_config_option[]=ssh|$SSH_DAEMON_CONFIG}|${OPTIONNAME}|"
|
||||
else
|
||||
LogText "Result: Option ${OPTIONNAME} not found in output"
|
||||
Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
fi
|
||||
else
|
||||
if IsVerbose; then Display --indent 4 --text "- SSH option: ${OPTIONNAME}" --result "SKIPPED (via config)" --color WHITE; fi
|
||||
if IsVerbose; then Display --indent 4 --text "- OpenSSH option: ${OPTIONNAME}" --result "SKIPPED (via config)" --color WHITE; fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
@ -290,32 +294,32 @@
|
|||
#################################################################################
|
||||
#
|
||||
# Test : SSH-7440
|
||||
# Description : AllowUsers / AllowGroups
|
||||
# Description : OpenSSH - AllowUsers / AllowGroups
|
||||
# Goal : Check if only a specific amount of users/groups can log in to the system
|
||||
if [ ${SSH_DAEMON_RUNNING} -eq 1 -a ! -z "${SSH_DAEMON_OPTIONS_FILE}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
Register --test-no SSH-7440 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check SSH option: AllowUsers and AllowGroups"
|
||||
if [ ${OPENSSHD_RUNNING} -eq 1 -a ! -z "${SSH_DAEMON_OPTIONS_FILE}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
|
||||
Register --test-no SSH-7440 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check OpenSSH option: AllowUsers and AllowGroups"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
FOUND=0
|
||||
# AllowUsers
|
||||
FIND=$(${EGREPBINARY} -i "^AllowUsers" ${SSH_DAEMON_OPTIONS_FILE} | ${AWKBINARY} '{ print $2 }')
|
||||
if [ ! -z "${FIND}" ]; then
|
||||
LogText "Result: AllowUsers set, with value ${FIND}"
|
||||
Display --indent 4 --text "- SSH option: AllowUsers" --result "${STATUS_FOUND}" --color GREEN
|
||||
Display --indent 4 --text "- OpenSSH option: AllowUsers" --result "${STATUS_FOUND}" --color GREEN
|
||||
FOUND=1
|
||||
else
|
||||
LogText "Result: AllowUsers is not set"
|
||||
Display --indent 4 --text "- SSH option: AllowUsers" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
Display --indent 4 --text "- OpenSSH option: AllowUsers" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
fi
|
||||
|
||||
# AllowGroups
|
||||
FIND=$(${EGREPBINARY} -i "^AllowGroups" ${SSH_DAEMON_OPTIONS_FILE} | ${AWKBINARY} '{ print $2 }')
|
||||
if [ ! -z "${FIND}" ]; then
|
||||
LogText "Result: AllowUsers set ${FIND}"
|
||||
Display --indent 4 --text "- SSH option: AllowGroups" --result "${STATUS_FOUND}" --color GREEN
|
||||
Display --indent 4 --text "- OpenSSH option: AllowGroups" --result "${STATUS_FOUND}" --color GREEN
|
||||
FOUND=1
|
||||
else
|
||||
LogText "Result: AllowGroups is not set"
|
||||
Display --indent 4 --text "- SSH option: AllowGroups" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
Display --indent 4 --text "- OpenSSH option: AllowGroups" --result "${STATUS_NOT_FOUND}" --color WHITE
|
||||
fi
|
||||
|
||||
if [ ${FOUND} -eq 1 ]; then
|
||||
|
@ -331,6 +335,7 @@
|
|||
#
|
||||
|
||||
Report "ssh_daemon_running=${SSH_DAEMON_RUNNING}"
|
||||
Report "openssh_daemon_running=${OPENSSHD_RUNNING}"
|
||||
|
||||
WaitForKeyPress
|
||||
|
||||
|
|
|
@ -251,8 +251,7 @@
|
|||
Register --test-no HTTP-6640 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Determining existence of specific Apache modules"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
# Check modules, module
|
||||
CheckItem "apache_module" "/mod_evasive([0-9][0-9])?.so"
|
||||
if [ ${ITEM_FOUND} -eq 1 ]; then
|
||||
if CheckItem "apache_module" "/mod_evasive([0-9][0-9])?.so"; then
|
||||
Display --indent 10 --text "mod_evasive: anti-DoS/brute force" --result "${STATUS_FOUND}" --color GREEN
|
||||
AddHP 3 3
|
||||
else
|
||||
|
@ -271,8 +270,7 @@
|
|||
Register --test-no HTTP-6641 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Determining existence of specific Apache modules"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
# Check modules, module
|
||||
CheckItem "apache_module" "/mod_(reqtimeout|qos).so"
|
||||
if [ ${ITEM_FOUND} -eq 1 ]; then
|
||||
if CheckItem "apache_module" "/mod_(reqtimeout|qos).so"; then
|
||||
Display --indent 10 --text "mod_reqtimeout/mod_qos" --result "${STATUS_FOUND}" --color GREEN
|
||||
AddHP 3 3
|
||||
else
|
||||
|
@ -290,8 +288,7 @@
|
|||
Register --test-no HTTP-6643 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Determining existence of specific Apache modules"
|
||||
if [ ${SKIPTEST} -eq 0 ]; then
|
||||
# Check modules, module
|
||||
CheckItem "apache_module" "/mod_security2.so"
|
||||
if [ ${ITEM_FOUND} -eq 1 ]; then
|
||||
if CheckItem "apache_module" "/mod_security2.so"; then
|
||||
Display --indent 10 --text "ModSecurity: web application firewall" --result "${STATUS_FOUND}" --color GREEN
|
||||
AddHP 3 3
|
||||
else
|
||||
|
|
48
lynis
48
lynis
|
@ -21,6 +21,11 @@
|
|||
# Lynis is an automated auditing tool for Unix based operating systems.
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
# 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.
|
||||
|
@ -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
|
||||
|
||||
#
|
||||
#################################################################################
|
||||
#
|
||||
|
@ -67,6 +67,9 @@
|
|||
#
|
||||
#################################################################################
|
||||
#
|
||||
# Check setuid bit
|
||||
if [ -u "$0" ]; then echo "The called binary has the set-user-id bit - As this is unusual, execution will be stopped."; exit 1; fi
|
||||
|
||||
# Work directory
|
||||
WORKDIR=$(pwd)
|
||||
|
||||
|
@ -139,8 +142,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 +194,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 +611,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
|
||||
|
@ -853,8 +854,17 @@ ${NORMAL}
|
|||
LogText "Action: checking plugin status in profile: ${PROFILE}"
|
||||
FIND3=$(grep "^plugin=${FIND2}" ${PROFILE})
|
||||
if [ ! -z "${FIND3}" ]; then
|
||||
LogText "Result: plugin enabled in profile (${PROFILE})"
|
||||
PLUGIN_ENABLED_STATE=1
|
||||
FOUND=0
|
||||
for I in ${DISABLED_PLUGINS}; do
|
||||
if [ "${I}" = "${FIND2}" ]; then
|
||||
FOUND=1
|
||||
LogText "Result: plugin ${FIND2} is specifically disabled"
|
||||
fi
|
||||
done
|
||||
if [ ${FOUND} -eq 0 ]; then
|
||||
LogText "Result: plugin enabled in profile (${PROFILE})"
|
||||
PLUGIN_ENABLED_STATE=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ ${PLUGIN_ENABLED_STATE} -eq 1 ]; then
|
||||
|
@ -948,7 +958,7 @@ ${NORMAL}
|
|||
for INCLUDE_TEST in ${INCLUDE_TESTS}; do
|
||||
INCLUDE_FILE="${INCLUDEDIR}/tests_${INCLUDE_TEST}"
|
||||
if [ -f ${INCLUDE_FILE} ]; then
|
||||
if SafePerms ${INCLUDE_FILE}; then
|
||||
if SafeFile ${INCLUDE_FILE}; then
|
||||
. ${INCLUDE_FILE}
|
||||
else
|
||||
LogText "Exception: skipping test category ${INCLUDE_TEST}, file ${INCLUDE_FILE} has bad permissions (should be 640, 600 or 400)"
|
||||
|
|
Loading…
Reference in New Issue