#!/bin/sh ################################################################################# # # Lynis # ------------------ # # Copyright 2007-2013, Michael Boelen # Copyright 2007-2021, CISOfy # # Website : https://cisofy.com # Blog : http://linux-audit.com # GitHub : https://github.com/CISOfy/lynis # # Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are # welcome to redistribute it under the terms of the GNU General Public License. # See LICENSE file for usage of this software. # ################################################################################# # # Networking # ################################################################################# # FOUNDPROMISC=0 # Promiscuous interfaces LOCAL_DNSRESOLVER_FOUND=0 # Local DNS resolver NUMBERACTIVENS=0 # Number of active nameservers DHCP_CLIENT_RUNNING=0 # DHCP client availability ARPWATCH_RUNNING=0 # ARP-cache based attack monitoring software ARPON_RUNNING=0 # ARP-cache based attack monitoring software # ################################################################################# # InsertSection "${SECTION_NETWORKING}" # ################################################################################# # # Test : NETW-2400 # Description : Test hostname for valid characters and length # Notes : FQDN: max 253 characters # : component: a-z, 0-9, hyphen, not start with hyphen, max 63 characters # dots allowed as separator Register --test-no NETW-2400 --weight L --network YES --category basics --description "Hostname length and value check" if [ ${SKIPTEST} -eq 0 ]; then # Test first the fully qualified domain name if [ ${#FQDN} -gt 253 ]; then # Too long LogText "Result: FQDN is more than 253 characters" Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "Hostname is too long (more than 253 characters)" elif [ ${#FQDN} -eq 0 ]; then # FQDN not defined LogText "Result: FQDN is not defined" if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_UNKNOWN}" --color YELLOW; fi else # Fine LogText "Result: FQDN is defined and not longer than 253 characters (${#FQDN} characters)" if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_OK}" --color GREEN; fi fi # Now test short hostname if [ ${#HOSTNAME} -eq 0 ]; then if IsVerbose; then Display --indent 2 --text "- Hostname (FQDN length)" --result "${STATUS_NONE}" --color RED; fi LogText "Result: hostname is not defined" else # Test length if [ ${#HOSTNAME} -gt 63 ]; then LogText "Result: hostname is more than 63 characters" Display --indent 2 --text "- Hostname (length)" --result "${STATUS_WARNING}" --color RED else LogText "Result: hostnamed is defined and not longer than 63 characters" fi # Test valid characters (normally a dot should not be in the name, but we can't be 100% sure we have short name) FIND=$(echo "${HOSTNAME}" | ${TRBINARY} -d '[:alnum:]\.\-') if [ -z "${FIND}" ]; then LogText "Result: good, no unexpected characters discovered in hostname" if IsVerbose; then Display --indent 2 --text "- Hostname (allowed characters)" --result "${STATUS_OK}" --color GREEN; fi else LogText "Result: unexpected characters discovered in hostname (characters: ${FIND}), which may impact network connectivity" Display --indent 2 --text "- Hostname (allowed characters)" --result "${STATUS_WARNING}" --color RED ReportWarning "${TEST_NO}" "Hostname contains invalid characters" "hostname" "text:See log file for invalid characters" fi fi fi # ################################################################################# # # Test : NETW-2600 # Description : Gather IPv6 configuration Register --test-no NETW-2600 --os "Linux" --weight L --network YES --category security --description "Checking IPv6 configuration" if [ ${SKIPTEST} -eq 0 ]; then IPV6_CONFIGURED=0 IPV6_ACCEPT_RA=255 IPV6_ACCEPT_REDIRECTS=255 IPV6_MANUAL_CONFIGURED=255 IPV6_ONLY=255 IPV6_MISCONFIGURED=0 IPV6_MISCONFIGURED_MTU=0 FIND=$(sysctl -a 2> /dev/null | ${GREPBINARY} "^net.ipv6" | ${SEDBINARY} "s/ = /=/") if [ -n "${FIND}" ]; then IPV6_CONFIGURED=1 for I in ${FIND}; do SYSCTL_KEY=$(echo ${I} | ${AWKBINARY} -F= '{ print $1 }') SYSCTL_VALUE=$(echo ${I} | ${AWKBINARY} -F= '{ print $2 }') case ${SYSCTL_KEY} in "net.ipv6.conf.default.accept_ra") if [ "${SYSCTL_VALUE}" = "1" ]; then IPV6_ACCEPT_RA=1; else IPV6_ACCEPT_RA=0; fi ;; "net.ipv6.conf.default.accept_redirects") if [ "${SYSCTL_VALUE}" = "1" ]; then IPV6_ACCEPT_REDIRECTS=1; else IPV6_ACCEPT_REDIRECTS=0; fi ;; "net.ipv6.bindv6only") if [ "${SYSCTL_VALUE}" = "1" ]; then IPV6_ONLY=1; else IPV6_ONLY=0; fi ;; "net.ipv6.conf.all.mtu" | "net.ipv6.conf.default.mtu") if [ ${SYSCTL_VALUE} -lt 1280 ]; then IPV6_MISCONFIGURED_MTU=1; fi ;; #if TestValue --function equals --value "${SYSCTL_VALUE}" --search "1"; then # echo "Found ${SYSCTL_VALUE}" #else # echo "Not found" #fi esac done else IPV6_MODE="disabled" fi # Check if we are manually configured (not accepting automatic configuration) if [ ${IPV6_ACCEPT_RA} -eq 0 -a ${IPV6_ACCEPT_REDIRECTS} -eq 0 ]; then IPV6_MANUAL_CONFIGURED=1 IPV6_MODE="manual" elif [ ${IPV6_ACCEPT_RA} -eq 1 -o ${IPV6_ACCEPT_REDIRECTS} -eq 1 ]; then IPV6_MODE="auto" else IPV6_MODE="disabled" fi LogText "Result: IPV6 mode is ${IPV6_MODE}" if [ ${IPV6_CONFIGURED} -eq 1 ]; then Display --indent 2 --text "- Checking IPv6 configuration" --result "${STATUS_ENABLED}" --color WHITE STATUS=$(echo ${IPV6_MODE} | ${TRBINARY} '[:lower:]' '[:upper:]') Display --indent 6 --text "Configuration method" --result "${STATUS}" --color WHITE if [ ${IPV6_ONLY} -eq 1 ]; then STATUS="${STATUS_YES}"; else STATUS="${STATUS_NO}"; fi LogText "Result: IPv6 only configuration: ${STATUS}" Display --indent 6 --text "IPv6 only" --result "${STATUS}" --color WHITE else Display --indent 2 --text "- Checking IPv6 configuration" --result "${STATUS_DISABLED}" --color WHITE fi # Configuration errors if [ ${IPV6_MISCONFIGURED_MTU} -eq 1 ]; then IPV6_MISCONFIGURED=1 LogText "Result: MTU of IPv6 interfaces should be 1280 or higher" Display --indent 6 --text "Error: MTU is too low" --result "${STATUS_WARNING}" --color RED ReportSuggestion "${TEST_NO}" "Check your MTU configuration of IPv6 interfaces" fi # Possible improvements: # - Check if we found IPv6 enabled nameservers # Report Report "ipv6_mode=${IPV6_MODE}" Report "ipv6_only=${IPV6_ONLY}" fi # ################################################################################# # # Test : NETW-2704 # Description : Basic nameserver configuration tests (connectivity) Register --test-no NETW-2704 --weight L --network YES --category security --description "Basic nameserver configuration tests" if [ ${SKIPTEST} -eq 0 ]; then Display --indent 2 --text "- Checking configured nameservers" LogText "Test: Checking /etc/resolv.conf file" if [ -f /etc/resolv.conf ]; then LogText "Result: Found /etc/resolv.conf file" FIND=$(${GREPBINARY} '^nameserver' /etc/resolv.conf | ${TRBINARY} -d '\t' | ${SEDBINARY} 's/nameserver*//g' | uniq | ${CUTBINARY} -d# -f1) if [ -n "${FIND}" ]; then Display --indent 4 --text "- Testing nameservers" LogText "Test: Querying nameservers" for I in ${FIND}; do LogText "Found nameserver: ${I}" Report "nameserver[]=${I}" # Check if a local resolver is available (like DNSMasq) if [ "${I}" = "::1" -o "${I}" = "127.0.0.1" -o "${I}" = "127.0.0.53" -o "${I}" = "127.0.1.1" -o "${I}" = "0.0.0.0" ]; then LOCAL_DNSRESOLVER_FOUND=1 fi if [ -n "${DIGBINARY}" ]; then # See if we can query something at the nameserver # 0=good, other=bad DNSRESPONSE=$(${DIGBINARY} +noall +time=3 +retry=0 @${I} ${FQDN} > /dev/null ; echo $?) if [ "${DNSRESPONSE}" = "0" ]; then Display --indent 8 --text "Nameserver: ${I}" --result "${STATUS_OK}" --color GREEN LogText "Nameserver ${I} seems to respond to queries from this host." # Count responsive nameservers NUMBERACTIVENS=$((NUMBERACTIVENS + 1)) else Display --indent 8 --text "Nameserver: ${I}" --result "NO RESPONSE" --color RED LogText "Result: nameserver ${I} does NOT respond" LogText "Exit-code from dig: ${DNSRESPONSE}" ReportSuggestion "${TEST_NO}" "Check connection to this nameserver and make sure no outbound DNS queries are blocked (port 53 UDP and TCP)." ReportWarning "${TEST_NO}" "Nameserver ${I} does not respond" fi else LogText "Result: Nameserver test for ${I} skipped, 'dig' not installed" Display --indent 6 --text "Nameserver: ${I}" --result "${STATUS_SKIPPED}" --color YELLOW fi done fi fi fi # ################################################################################# # # Test : NETW-2705 # Description : Basic nameserver configuration tests (connectivity) if [ ${LOCAL_DNSRESOLVER_FOUND} -eq 0 ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no NETW-2705 --preqs-met ${PREQS_MET} --weight L --network YES --category security --description "Check availability two nameservers" if [ ${SKIPTEST} -eq 0 ]; then SKIP=0 if [ -n "${DIGBINARY}" ]; then if [ ${NUMBERACTIVENS} -lt 2 ]; then Display --indent 4 --text "- Minimal of 2 responsive nameservers" --result "${STATUS_WARNING}" --color RED LogText "Result: less than 2 responsive nameservers found" ReportWarning "${TEST_NO}" "Couldn't find 2 responsive nameservers" LogText "Note: Non responsive nameservers can give problems for your system(s). Like the lack of recursive lookups, bad connectivity to update servers etc." ReportSuggestion "${TEST_NO}" "Check your resolv.conf file and fill in a backup nameserver if possible" AddHP 1 2 else Display --indent 4 --text "- Minimal of 2 responsive nameservers" --result "${STATUS_OK}" --color GREEN LogText "Result: found at least 2 responsive nameservers" AddHP 3 3 fi else Display --indent 4 --text "- Minimal of 2 responsive nameservers" --result "${STATUS_SKIPPED}" --color YELLOW LogText "Result: dig not installed, test can't be fully performed" fi else LogText "Result: Test most likely skipped due having local resolver in /etc/resolv.conf" fi # ################################################################################# # # Test : NETW-2706 # Description : Check systemd-resolve output and upstream DNSSEC status # Notes : Ubuntu 16.04 uses systemd-resolve, newer ones most likely resolvectl if [ -n "${RESOLVECTLBINARY}" ]; then PREQS_MET="YES" RESOLVE_CMD="${RESOLVECTLBINARY}" RESOLVE_CMD_PARAM="statistics" elif [ -n "$(command -v systemd-resolve 2> /dev/null)" ]; then PREQS_MET="YES" RESOLVE_CMD="$(command -v systemd-resolve 2> /dev/null)" RESOLVE_CMD_PARAM="--statistics" else PREQS_MET="NO" fi Register --test-no NETW-2706 --preqs-met "${PREQS_MET}" --weight L --network YES --category security --description "Check systemd-resolved and upstream DNSSEC status" if [ ${SKIPTEST} -eq 0 ]; then SKIP=0 DNSSEC_STATUS=$(${RESOLVE_CMD} ${RESOLVE_CMD_PARAM} 2> /dev/null | ${AWKBINARY} -F ":" '/DNSSEC supported/ { print $2 }' | ${TRBINARY} -d ' ') if [ "${DNSSEC_STATUS}" = "yes" ]; then Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_YES}" --color GREEN LogText "Result: DNSSEC supported by systemd-resolved and upstream DNS servers" elif [ "${DNSSEC_STATUS}" = "no" ]; then Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_NO}" --color YELLOW LogText "Result: DNSSEC not supported by systemd-resolved or upstream DNS servers" else Display --indent 4 --text "- DNSSEC supported (systemd-resolved)" --result "${STATUS_UNKNOWN}" --color RED LogText "Result: command '${RESOLVE_CMD} ${RESOLVE_CMD_PARAM}' returned an error. Please run command manually to check for details." fi else LogText "Result: Test most likely skipped due to not having resolvectl" fi # ################################################################################# # # Test : NETW-3001 # Description : Find default gateway (route) # More info : BSD: ^default Linux: 0.0.0.0 if [ -n "${NETSTATBINARY}" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no NETW-3001 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Find default gateway (route)" if [ $SKIPTEST -eq 0 ]; then LogText "Test: Searching default gateway(s)" FIND=$(${NETSTATBINARY} -rn | ${EGREPBINARY} "^0.0.0.0|default" | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f2) if [ -n "${FIND}" ]; then for I in ${FIND}; do LogText "Result: Found default gateway ${I}" Report "default_gateway[]=${I}" done Display --indent 2 --text "- Checking default gateway" --result "${STATUS_DONE}" --color GREEN else LogText "Result: No default gateway found" Display --indent 2 --text "- Checking default gateway" --result "NONE FOUND" --color WHITE fi fi # ################################################################################# # # Test : NETW-3004 # Description : Find available network interfaces Register --test-no NETW-3004 --weight L --network NO --category security --description "Search for available network interfaces" if [ ${SKIPTEST} -eq 0 ]; then FIND="" case ${OS} in AIX) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} "flags=" | ${AWKBINARY} -F ":" '{ print $1 }') ;; Linux) if [ -n "${IPBINARY}" ]; then FIND=$(${IPBINARY} link show 2> /dev/null | ${GREPBINARY} "^[0-9]" | ${AWKBINARY} '{ print $2 }' | ${SEDBINARY} 's/://g') elif [ -n "${IFCONFIGBINARY}" ]; then FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ( $2 == "Link" ) { print $1 }}') fi ;; DragonFly|FreeBSD|macOS|NetBSD) FIND=$(${IFCONFIGBINARY} -l 2> /dev/null) ;; OpenBSD|Solaris) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} "flags=" | ${AWKBINARY} -F ": " '{ print $1 }') ;; *) # Having a system currently unsupported? Share your details to determine network interfaces ReportException "${TEST_NO}:1" "No support for this OS (${OS}) to find available network interfaces" ;; esac if HasData "${FIND}"; then for ITEM in ${FIND}; do NETWORK_INTERFACES="${NETWORK_INTERFACES}|${ITEM}" LogText "Found network interface: ${ITEM}" Report "network_interface[]=${ITEM}" done else ReportException "${TEST_NO}:1" "No interfaces found on this system (OS=${OS})" fi fi # ################################################################################# # # Test : NETW-3006 # Description : Get network MAC addresses Register --test-no NETW-3006 --weight L --network NO --category security --description "Get network MAC addresses" if [ ${SKIPTEST} -eq 0 ]; then FIND="" case ${OS} in AIX) FIND=$(lscfg -vl ent* | ${GREPBINARY} "Network Address" | ${CUTBINARY} -d"." -f14 | ${AWKBINARY} '{ ctr=1; i=1; while (ctr <= 6) { d[ctr++]=substr($0,i,2);i=i+2 } printf("%s:%s:%s:%s:%s:%s\n",d[1],d[2],d[3],d[4],d[5],d[6]) }') ;; DragonFly|FreeBSD) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="ether") print $2 }' | ${SORTBINARY} -u) ;; Linux) if [ -n "${IFCONFIGBINARY}" ]; then FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} "HWaddr" | ${AWKBINARY} '{ if ($4=="HWaddr") print $5 }' | ${SORTBINARY} -u) # CentOS 7.x and others may return nothing. Let's retry with 'ether' field. if [ -z "${FIND}" ]; then FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="ether") print $2 }' | ${SORTBINARY} -u) fi else if [ -n "${IPBINARY}" ]; then LogText "Test: Using ip binary to gather hardware addresses" FIND=$(${IPBINARY} link 2> /dev/null | ${GREPBINARY} "link/ether" | ${AWKBINARY} '{ print $2 }') else ReportException "${TEST_NO}:2" "Missing ifconfig or ip command to collect hardware address (MAC)" fi fi ;; macOS) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="lladdr" || $1=="ether") print $2 }' | ${SORTBINARY} -u) ;; NetBSD) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="address:") print $2 }' | ${SORTBINARY} -u) ;; OpenBSD) FIND=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1=="lladdr") print $2 }' | ${SORTBINARY} -u) ;; Solaris) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="ether") print $2 }' | ${SORTBINARY} -u) ;; *) # Having a system currently unsupported? Share your details to determine MAC information ReportException "${TEST_NO}:1" "No support for this OS (${OS}) to find MAC information" ;; esac for ITEM in ${FIND}; do LogText "Found MAC address: ${ITEM}" Report "network_mac_address[]=${ITEM}" done fi # ################################################################################# # # Test : NETW-3008 # Description : Get network IPv4/6 addresses Register --test-no NETW-3008 --weight L --network NO --category security --description "Get network IP addresses" if [ ${SKIPTEST} -eq 0 ]; then FIND=""; FIND2="" case ${OS} in AIX) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }') FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") print $2 }') ;; DragonFly|FreeBSD|NetBSD) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }') FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") print $2 }') ;; Linux) if [ -n "${IFCONFIGBINARY}" ]; then FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }' | ${CUTBINARY} -d ':' -f2) # Version which works for multiple types of ifconfig (e.g. Slackware) FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6" && $2=="addr:") { print $3 } else { if ($1=="inet6" && $3=="prefixlen") { print $2 } } }') else if [ -n "${IPBINARY}" ]; then LogText "Test: Using ip binary to gather IP addresses" FIND=$(${IPBINARY} addr 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") { print $2 }}' | ${SEDBINARY} 's/\/.*//') FIND2=$(${IPBINARY} addr 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") { print $2 }}' | ${SEDBINARY} 's/\/.*//') else ReportException "${TEST_NO}:2" "Missing ifconfig or ip command to collect hardware address (MAC)" fi fi ;; macOS) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }') FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") print $2 }') ;; OpenBSD) FIND=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }') FIND2=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") print $2 }') ;; Solaris) FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet") print $2 }') FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1=="inet6") print $2 }') ;; *) LogText "Result: no support yet for this OS (${OS}) to find IP address information. You can help improving this test by submitting your details." ReportException "${TEST_NO}:1" "IP address information test not implemented for this operating system" ;; esac # IPv4 for ITEM in ${FIND}; do LogText "Found IPv4 address: ${ITEM}" Report "network_ipv4_address[]=${ITEM}" done # IPv6 for ITEM in ${FIND2}; do LogText "Found IPv6 address: ${ITEM}" Report "network_ipv6_address[]=${ITEM}" done fi # ################################################################################# # # Test : NETW-3012 # 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 DragonFly | FreeBSD) if [ -n "${SOCKSTATBINARY}" ]; then FIND=$(${SOCKSTATBINARY} | ${AWKBINARY} '{ if ($7 ~ /\*:\*/) print $5"|"$6"|"$2"|" }' | ${SORTBINARY} -u) # To strip off IP's: ${SEDBINARY} 's/|.*:/|/' else FIND="" fi FIND2="" ;; Linux) if [ -n "${SSBINARY}" ]; then LogText "Test: Retrieving ss information to find listening ports" DATA=$(${SSBINARY} --query=udp,tcp -plnt | ${AWKBINARY} '{ if ($1!="Netid") { print "raw,ss,v1|"$1"|"$5"|"$7"|" }}' | ${SEDBINARY} 's/pid=[0-9]\{1,\},fd=[0-9]\{1,\}//g' | ${SEDBINARY} 's/users://' | ${SEDBINARY} 's/,)//g' | ${TRBINARY} -d '()"') elif [ -n "${NETSTATBINARY}" ]; then LogText "Test: Retrieving netstat information to find listening ports" # 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 ReportException "${TEST_NO}:1" "netstat and ss binary missing to gather listening ports" fi ;; macOS) if [ -n "${LSOFBINARY}" ]; then LogText "Test: Retrieving lsof information to find listening ports" # UDP and TCP combined FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -i -P | ${AWKBINARY} '{ print $9"|"$8"|"$1"|" }' | ${SEDBINARY} 's/\(.*\)\-\>.*\(\|.*\)/\1\2/' | ${SEDBINARY} 's/\*/'$IP'/' | ${SORTBINARY} -u | ${GREPBINARY} -v "NAME") else FIND="" fi # Not needed as we have a combined test FIND2="" ;; NetBSD) if [ -n "${SOCKSTATBINARY}" ]; then LogText "Test: Retrieving sockstat information to find listening ports" FIND=$(${SOCKSTATBINARY} 2> /dev/null | ${AWKBINARY} '{ if ($7 ~ /\*.\*/) print $5"|"$6"|"$2"|" }' | ${SORTBINARY} -u) else FIND="" fi FIND2="" ;; OpenBSD) if [ -n "${NETSTATBINARY}" ]; then LogText "Test: Retrieving netstat information to find listening ports" # UDP FIND=$(${NETSTATBINARY} -an 2> /dev/null | ${GREPBINARY} "^udp" | ${AWKBINARY} '{ print $4"|"$1"||" }') # TCP FIND2=$(${NETSTATBINARY} -an 2> /dev/null | ${GREPBINARY} "^tcp" | ${AWKBINARY} '{ if($6=="LISTEN") { print $4"|"$1"||" }}') else ReportException "${TEST_NO}:3" "netstat missing to gather listening ports" fi ;; Solaris) if [ -n "${NETSTATBINARY}" ]; then LogText "Test: Retrieving netstat information to find listening ports" FIND=$(${NETSTATBINARY} -an -P udp | ${AWKBINARY} '{ if($7=="LISTEN") { print $1"|udp|LISTEN|" }}') FIND2=$(${NETSTATBINARY} -an -P tcp | ${AWKBINARY} '{ if($7=="LISTEN") { print $1"|tcp|LISTEN|" }}') else ReportException "${TEST_NO}:4" "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 [ -n "${DATA}" ]; then for ITEM in ${DATA}; do COUNT=$((COUNT + 1)) Report "network_listen[]=${ITEM}" done fi if [ -n "${FIND}" ]; then for ITEM in ${FIND}; do COUNT=$((COUNT + 1)) LogText "Found listening info: ${ITEM}" Report "network_listen_port[]=${ITEM}" done fi if [ -n "${FIND2}" ]; then for ITEM in ${FIND2}; do COUNT=$((COUNT + 1)) LogText "Found listening info: ${ITEM}" Report "network_listen_port[]=${ITEM}" done fi 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 fi fi # ################################################################################# # # Test : NETW-3014 # Description : Checking promiscuous interfaces (BSD) # Note : FreeBSD and others if [ "${OS}" = "DragonFly" -o "${OS}" = "FreeBSD" -o "${OS}" = "NetBSD" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no NETW-3014 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking promiscuous interfaces (BSD)" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Checking promiscuous interfaces (FreeBSD)" FIND=$(${IFCONFIGBINARY} 2> /dev/null | ${GREPBINARY} PROMISC | ${CUTBINARY} -d ':' -f1) if HasData "${FIND}"; then LogText "Result: Promiscuous interfaces: ${FIND}" for ITEM in ${FIND}; do WHITELISTED=0 for PROFILE in ${PROFILES}; do Debug "Checking if interface ${ITEM} is whitelisted in profile ${PROFILE}" ISWHITELISTED=$(${GREPBINARY} "^if_promisc:${ITEM}:" ${PROFILE}) if HasData "${ISWHITELISTED}"; then WHITELISTED=1 LogText "Result: this interface was whitelisted in profile (${PROFILE})" fi done # Check if this interface was whitelisted if [ ${WHITELISTED} -eq 0 ]; then FOUNDPROMISC=1 ReportWarning "${TEST_NO}" "Found promiscuous interface (${ITEM})" LogText "Note: some tools put an interface into promiscuous mode, to capture/log network traffic" else LogText "Result: Found promiscuous interface ${ITEM} (*whitelisted via profile*)" fi done fi # Show result if [ ${FOUNDPROMISC} -eq 0 ]; then Display --indent 2 --text "- Checking promiscuous interfaces" --result "${STATUS_OK}" --color GREEN LogText "Result: No promiscuous interfaces found" else Display --indent 2 --text "- Checking promiscuous interfaces" --result "${STATUS_WARNING}" --color RED fi fi # ################################################################################# # # Test : NETW-3015 # Description : Checking promiscuous interfaces (Linux) Register --test-no NETW-3015 --os Linux --weight L --network NO --category security --description "Checking promiscuous interfaces (Linux)" if [ ${SKIPTEST} -eq 0 ]; then FOUNDPROMISC=99 NETWORK="" USE_IP_INSTEAD_IFCONFIG=0 if [ -n "${IPBINARY}" ]; then LogText "Test: Using ip binary to retrieve network interfaces" NETWORK=$(${IPBINARY} -o link 2> /dev/null | ${GREPBINARY} "^[0-9]" | ${AWKBINARY} '{print $2 }' | ${TRBINARY} -d ':') USE_IP_INSTEAD_IFCONFIG=1 elif [ -n "${IFCONFIGBINARY}" ]; then LogText "Test: Using ifconfig binary to retrieve network interfaces" NETWORK=$(${IFCONFIGBINARY} 2> /dev/null | ${GREPBINARY} Link | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f1) fi LogText "Test: Checking all interfaces to discover any with promiscuous mode enabled" if [ -n "${NETWORK}" ]; then FOUNDPROMISC=0 for I in ${NETWORK}; do if [ ${USE_IP_INSTEAD_IFCONFIG} -eq 1 ]; then FIND=$(${IPBINARY} -o -d link show ${I} 2> /dev/null | ${GREPBINARY} "promiscuity [1-9]") else FIND=$(${IFCONFIGBINARY} ${I} 2> /dev/null | ${GREPBINARY} PROMISC) fi if [ -n "${FIND}" ]; then LogText "Result: Promiscuous interface: ${I}" ISWHITELISTED=$(${GREPBINARY} "^if_promisc:${I}:" ${PROFILE}) if [ -z "${ISWHITELISTED}" ]; then FOUNDPROMISC=1 ReportWarning "${TEST_NO}" "Found promiscuous interface" "${I}" "text:Determine if this mode is required or whitelist interface in profile" LogText "Note: some tools put an interface into promiscuous mode, to capture/log network traffic" else LogText "Result: Found promiscuous interface ${I} (*whitelisted via profile*)" fi fi done else LogText "Result: no network interfaces discovered, so nothing tested" fi # Show result if [ ${FOUNDPROMISC} -eq 0 ]; then Display --indent 2 --text "- Checking promiscuous interfaces" --result "${STATUS_OK}" --color GREEN LogText "Result: No promiscuous interfaces found" elif [ ${FOUNDPROMISC} -eq 1 ]; then Display --indent 2 --text "- Checking promiscuous interfaces" --result "${STATUS_WARNING}" --color RED else Display --indent 2 --text "- Checking promiscuous interfaces" --result "${STATUS_UNKNOWN}" --color YELLOW fi fi # ################################################################################# # # Do you have a multipath configuration on Linux or other OS? Create a related test and send in a pull request on GitHub # Test : NETW-3020 TODO # Description : Checking multipath configuration # ################################################################################# # # Test : NETW-3028 # Description : Checking for many waiting connections # Type : Performance # Notes : It is common to see a healthy web server seeing to have several thousands of TCP connections in WAIT state if [ ! "${NETSTATBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi Register --test-no NETW-3028 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Checking connections in WAIT state" if [ ${SKIPTEST} -eq 0 ]; then LogText "Test: Using netstat for check for connections in WAIT state" FIND=$(${NETSTATBINARY} -an | ${GREPBINARY} WAIT | ${WCBINARY} -l | ${AWKBINARY} '{ print $1 }') if IsEmpty "${OPTIONS_CONN_MAX_WAIT_STATE}"; then OPTIONS_CONN_MAX_WAIT_STATE="5000"; fi LogText "Result: currently ${FIND} connections are in a waiting state (max configured: ${OPTIONS_CONN_MAX_WAIT_STATE})." if [ ${FIND} -gt ${OPTIONS_CONN_MAX_WAIT_STATE} ]; then Display --indent 2 --text "- Checking waiting connections" --result "${STATUS_WARNING}" --color YELLOW ReportSuggestion "${TEST_NO}" "Determine why system has many connections in WAIT state (${FIND})" else Display --indent 2 --text "- Checking waiting connections" --result "${STATUS_OK}" --color GREEN LogText "Result: ${FIND} connections are in WAIT state" fi fi # ################################################################################# # # Test : NETW-3030 # Description : Checking for DHCP client Register --test-no NETW-3030 --weight L --network NO --category security --description "Checking DHCP client status" if [ ${SKIPTEST} -eq 0 ]; then if IsRunning "dhclient" || IsRunning "dhcpcd" || IsRunning "udhcpc"; then Display --indent 2 --text "- Checking status DHCP client" --result "${STATUS_RUNNING}" --color WHITE DHCP_CLIENT_RUNNING=1 else Display --indent 2 --text "- Checking status DHCP client" --result "${STATUS_NOT_ACTIVE}" --color WHITE fi fi # ################################################################################# # # Test : NETW-3032 # Description : Checking for ARP spoofing and related monitoring software Register --test-no NETW-3032 --os Linux --weight L --network NO --category security --description "Checking for ARP monitoring software" if [ ${SKIPTEST} -eq 0 ]; then FOUND=0 # addrwatch if IsRunning "addrwatch"; then FOUND=1 fi # arpwatch if IsRunning "arpwatch"; then FOUND=1 ARPWATCH_RUNNING=1 fi # arpon if IsRunning "arpon"; then FOUND=1 ARPON_RUNNING=1 fi 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 (addrwatch,arpwatch,arpon)" fi fi # ################################################################################# # # Test : NETW-3200 # Description : Determine available network protocols # Notes : See all available supported modules: ls -d /lib/modules/$(uname -r )/kernel/net # To see active/enabled protocols: ls -d /proc/sys/net Register --test-no NETW-3200 --weight L --network YES --category security --description "Determine available network protocols" if [ ${SKIPTEST} -eq 0 ]; then TESTED=0 FOUND_UNCOMMON_PROTOCOL_ENABLED=0 case ${OS} in Linux) TESTED=1 LogText "Test: checking the status of some network protocols that typically are not used" UNCOMMON_PROTOCOLS="dccp sctp rds tipc" for P in ${UNCOMMON_PROTOCOLS}; do LogText "Test: now checking module '${P}'" if ! SkipAtomicTest "${TEST_NO}:${P}"; then UNCOMMON_PROTOCOL_DISABLED=0 # First check modprobe.conf if [ -f ${ROOTDIR}etc/modprobe.conf ]; then DATA=$(${GREPBINARY} "^install \+${P} \+/bin/true$" ${ROOTDIR}etc/modprobe.conf) if [ -n "${DATA}" ]; then LogText "Result: found ${P} module disabled via modprobe.conf" UNCOMMON_PROTOCOL_DISABLED=1 fi fi # Then additional modprobe configuration files if [ -d ${ROOTDIR}etc/modprobe.d ]; then # Return file names (-l) and suppress errors (-s) DATA=$(${GREPBINARY} -l -s "^install \+${P} \+/bin/true$" ${ROOTDIR}etc/modprobe.d/*) if [ -n "${DATA}" ]; then UNCOMMON_PROTOCOL_DISABLED=1 for F in ${DATA}; do LogText "Result: found ${P} module disabled via ${F}" done fi fi if [ ${UNCOMMON_PROTOCOL_DISABLED} -eq 0 ]; then ReportSuggestion "${TEST_NO}" "Determine if protocol '${P}' is really needed on this system" Report "uncommon_network_protocol_enabled=${P}" FOUND_UNCOMMON_PROTOCOL_ENABLED=1 fi fi done ;; *) LogText "This test has no routine yet for this operating system." Debug "No routine implemented yet for this operating system to check for available network protocols" ;; esac if [ ${TESTED} -eq 1 ]; then if [ ${FOUND_UNCOMMON_PROTOCOL_ENABLED} -eq 1 ]; then Display --indent 2 --text "- Uncommon network protocols" --result "${FOUND}" --color YELLOW else Display --indent 2 --text "- Uncommon network protocols" --result "${STATUS_NOT_FOUND}" --color GREEN fi fi unset DATA F FOUND TESTED UNCOMMON_PROTOCOLS fi # ################################################################################# # WaitForKeyPress # #================================================================================ # Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com