Created
October 23, 2022 14:12
-
-
Save amekusa/83b059b9fe926622159266fb400df936 to your computer and use it in GitHub Desktop.
Fixing grep/egrep warnings in Rkhunter 1.4.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- rkhunter.1.4.6-2 2022-10-23 17:19:51.000000000 +0900 | |
| +++ rkhunter.1.4.6-2.patched 2022-10-23 23:07:17.000000000 +0900 | |
| @@ -1,5 +1,8 @@ | |
| #!/bin/sh | |
| +# This is PATCHED version of rkhunter 1.4.6-2 to eliminate grep and egrep warnings. | |
| +# Diff vs the original: https://github.com/amekusa/arch-setup/compare/825d7ac..b2aceeb | |
| + | |
| # | |
| # rkhunter -- Scan the system for rootkits and other known security issues. | |
| # | |
| @@ -70,7 +73,7 @@ | |
| # we exec to log everything to the debug file. | |
| # | |
| -if [ -n "`echo \"$*\" | grep '\-\-debug'`" ]; then | |
| +if [ -n "`echo \"$*\" | grep -- '--debug'`" ]; then | |
| RKHDEBUGFILE="" | |
| RKHDEBUGBASE="/tmp/rkhunter-debug" | |
| @@ -181,7 +184,7 @@ | |
| # used. If it is, then some typical grep tests will fail. | |
| # | |
| -if [ "`echo \"rkh-grep-test\" | grep '^\+'`" = "rkh-grep-test" ]; then | |
| +if [ "`echo \"rkh-grep-test\" | grep '^+'`" = "rkh-grep-test" ]; then | |
| alias grep='grep -E' | |
| fi | |
| @@ -948,9 +951,9 @@ | |
| # | |
| if [ "${OPT_NAME}" = "SHARED_LIB_WHITELIST" ]; then | |
| - RKHTMPVAR=`echo "${OPT_VALUE}" | egrep '(^|[^\\])[][?*]'` | |
| + RKHTMPVAR=`echo "${OPT_VALUE}" | grep -E '(^|[^\\])[][?*]'` | |
| else | |
| - RKHTMPVAR=`echo "${OPT_VALUE}" | egrep '(^|[^\\])[][?*{}]'` | |
| + RKHTMPVAR=`echo "${OPT_VALUE}" | grep -E '(^|[^\\])[][?*{}]'` | |
| fi | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| @@ -989,7 +992,7 @@ | |
| # The code is left here since we may need something very similar for overloaded options. | |
| # overloaded options - ALLOWPROCDELFILE PORT_PATH_WHITELIST RTKT_FILE_WHITELIST | |
| # if [ "${OPT_NAME}" = "BINDIR" ]; then | |
| -# if [ -n "`echo \"${FNAME}\" | grep '^\+'`" ]; then | |
| +# if [ -n "`echo \"${FNAME}\" | grep '^+'`" ]; then | |
| # FNAME=`echo "${FNAME}" | cut -c2-` | |
| # fi | |
| # fi | |
| @@ -1000,7 +1003,7 @@ | |
| # Also check that '/' has not been set. | |
| # | |
| - if [ -n "`echo \"${FNAME}\" | egrep '(^[./]*$)|[;&]|/\.\./'`" ]; then | |
| + if [ -n "`echo \"${FNAME}\" | grep -E '(^[./]*$)|[;&]|/\.\./'`" ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Invalid pathname: ${FNAME}" | |
| @@ -1134,7 +1137,7 @@ | |
| # | |
| if [ "${OPT_NAME}" = "SHARED_LIB_WHITELIST" ]; then | |
| - if [ -n "`echo \"${FNAME}\" | egrep '\\$\\{?(ORIGIN|LIB|PLATFORM)\\}?'`" ]; then | |
| + if [ -n "`echo \"${FNAME}\" | grep -E '\\$\\{?(ORIGIN|LIB|PLATFORM)\\}?'`" ]; then | |
| continue | |
| fi | |
| fi | |
| @@ -2522,7 +2525,7 @@ | |
| PREPEND_PATHS="" | |
| for DIR in ${BINPATHS}; do | |
| - if [ -n "`echo ${DIR} | grep '^\+'`" ]; then | |
| + if [ -n "`echo ${DIR} | grep '^+'`" ]; then | |
| DIR=`echo ${DIR} | cut -c2-` | |
| PREPEND_PATHS="${PREPEND_PATHS} ${DIR}" | |
| fi | |
| @@ -2532,7 +2535,7 @@ | |
| for DIR in ${PREPEND_PATHS} ${RKHROOTPATH} ${BINPATHS}; do | |
| - if [ -n "`echo ${DIR} | grep '^\+'`" ]; then | |
| + if [ -n "`echo ${DIR} | grep '^+'`" ]; then | |
| # These will already be in PREPEND_PATHS. | |
| continue | |
| elif [ -z "`echo ${DIR} | grep '^/'`" ]; then | |
| @@ -3848,7 +3851,7 @@ | |
| # | |
| for RKHTMPVAR2 in ${RKHTMPVAR}; do | |
| - if [ -n "`echo \"${RKHTMPVAR2}\" | egrep -i '^(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| + if [ -n "`echo \"${RKHTMPVAR2}\" | grep -E -i '^(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| PROTO=`echo ${RKHTMPVAR2} | cut -d: -f1 | tr '[:lower:]' '[:upper:]'` | |
| PORT=`echo ${RKHTMPVAR2} | cut -d: -f2` | |
| @@ -3899,7 +3902,7 @@ | |
| PROTO="" | |
| # Dig out the protocol and port number, if present. | |
| - if [ -n "`echo \"${RKHTMPVAR2}\" | egrep -i '.:(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| + if [ -n "`echo \"${RKHTMPVAR2}\" | grep -E -i '.:(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| PROTO=`echo "${RKHTMPVAR2}" | sed -e 's/^.*:\([a-zA-Z]*\):[1-9][0-9]*$/\1/'` | |
| PORT=`echo "${RKHTMPVAR2}" | sed -e 's/^.*:\([1-9][0-9]*\)$/\1/'` | |
| @@ -4839,7 +4842,7 @@ | |
| fi | |
| fi | |
| - if [ -n "`echo \"${HASH_FUNC}\" | egrep -i '^(MD5|SHA1|SHA224|SHA256|SHA384|SHA512|RIPEMD160|WHIRLPOOL|NONE)$'`" ]; then | |
| + if [ -n "`echo \"${HASH_FUNC}\" | grep -E -i '^(MD5|SHA1|SHA224|SHA256|SHA384|SHA512|RIPEMD160|WHIRLPOOL|NONE)$'`" ]; then | |
| HASH_FUNC=`echo "${HASH_FUNC}" | tr '[:lower:]' '[:upper:]'` | |
| fi | |
| @@ -6412,7 +6415,7 @@ | |
| OSNAME="${OSNAME} `sw_vers 2>/dev/null | grep '^ProductVersion:' | sed -e 's/ProductVersion:[ ]*//'`" | |
| # OSNAME="${OSNAME} `sysctl kern.version 2>/dev/null | sed -e 's/^kern.version = //' | cut -d: -f1`" | |
| - if [ -n "`sysctl -a 2>/dev/null | egrep '^(hw\.optional\.x86_64|hw\.optional\.64bitops|hw\.cpu64bit_capable).*1$'`" ]; then | |
| + if [ -n "`sysctl -a 2>/dev/null | grep -E '^(hw\.optional\.x86_64|hw\.optional\.64bitops|hw\.cpu64bit_capable).*1$'`" ]; then | |
| OSNAME="${OSNAME} (64-bit capable)" | |
| fi | |
| ;; | |
| @@ -6708,7 +6711,7 @@ | |
| # this is what RPM does). | |
| # | |
| - RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT_ARCH}" | egrep ':(x86_64|ia64):' 2>/dev/null | tail ${TAIL_OPT}1` | |
| + RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT_ARCH}" | grep -E ':(x86_64|ia64):' 2>/dev/null | tail ${TAIL_OPT}1` | |
| test -z "${RPM_QUERY_RESULT}" && RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT_ARCH}" | tail ${TAIL_OPT}1` | |
| @@ -6883,7 +6886,7 @@ | |
| if [ -n "${PKGNAME}" ]; then | |
| if [ -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then | |
| FILNAM=`echo "${FNAME}" | sed -e 's:^/::; s:\.:\\\.:g'` | |
| - SYSHASH=`egrep "( |\./)${FILNAM}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" 2>/dev/null | cut -d' ' -f1` | |
| + SYSHASH=`grep -E "( |\./)${FILNAM}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" 2>/dev/null | cut -d' ' -f1` | |
| test -n "${SYSHASH}" && FILE_IS_PKGD=1 | |
| fi | |
| fi | |
| @@ -6925,7 +6928,7 @@ | |
| SYSHASH="" | |
| RKHTMPVAR=`${HASH_CMD} "${FNAME}" 2>&1` | |
| - if [ -n "`echo \"${RKHTMPVAR}\" | egrep 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| + if [ -n "`echo \"${RKHTMPVAR}\" | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | tr '\n' ':' | sed -e 's/:$//'` | |
| else | |
| @@ -7311,13 +7314,13 @@ | |
| case $MIRRORS_MODE in | |
| 0) | |
| - MIRROR=`egrep -i '^(local|remote|mirror)=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| + MIRROR=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| 1) | |
| - MIRROR=`egrep -i '^local=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| + MIRROR=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| 2) | |
| - MIRROR=`egrep -i '^remote=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| + MIRROR=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| esac | |
| @@ -7337,13 +7340,13 @@ | |
| case $MIRRORS_MODE in | |
| 0) | |
| - MIRROR=`egrep -i '^(local|remote|mirror)=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| + MIRROR=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| 1) | |
| - MIRROR=`egrep -i '^local=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| + MIRROR=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| 2) | |
| - MIRROR=`egrep -i '^remote=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| + MIRROR=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| esac | |
| @@ -7370,7 +7373,7 @@ | |
| # Next get the remaining mirrors. | |
| # | |
| - OTHERMIRRORS=`egrep -i '^(local|remote|mirror)=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" | grep -v "^${MIRROR}\$"` | |
| + OTHERMIRRORS=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | grep -v "^${MIRROR}\$"` | |
| # | |
| @@ -7459,13 +7462,13 @@ | |
| case $MIRRORS_MODE in | |
| 0) | |
| - MIRROR_COUNT=`egrep -i '^(local|remote|mirror)=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| + MIRROR_COUNT=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| 1) | |
| - MIRROR_COUNT=`egrep -i '^local=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| + MIRROR_COUNT=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| 2) | |
| - MIRROR_COUNT=`egrep -i '^remote=https?://[-A-Za-z0-9\+@#/%=_:,.]*[-A-Za-z0-9\+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| + MIRROR_COUNT=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| esac | |
| @@ -7991,7 +7994,7 @@ | |
| # Now check to see if any unknown options have been configured. | |
| # | |
| - RKHTMPVAR=`egrep -h -v '^[ ]*(#|$)' ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES}` | |
| + RKHTMPVAR=`grep -E -h -v '^[ ]*(#|$)' ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES}` | |
| IFS=$IFSNL | |
| @@ -9587,7 +9590,7 @@ | |
| rpc.nfsd:tcp.log:Sniffer installed | |
| sshd:/dev/ptyxx:OpenBSD Rootkit | |
| sshd:/.config:SHV4 Rootkit | |
| - sshd:+\\$.*\\$\!.*\!\!\\$:Backdoored SSH daemon installed | |
| + sshd:+\\$.*\\$!.*!!\\$:Backdoored SSH daemon installed | |
| sshd:backdoor.h:Trojaned SSH daemon | |
| sshd:backdoor_active:Trojaned SSH daemon | |
| sshd:magic_pass_active:Trojaned SSH daemon | |
| @@ -10712,7 +10715,7 @@ | |
| done | |
| - if [ -n "`echo \"${RKHTMPVAR}\" | egrep 'libsafe|missing|empty'`" ]; then | |
| + if [ -n "`echo \"${RKHTMPVAR}\" | grep -E 'libsafe|missing|empty'`" ]; then | |
| display --to LOG --type WARNING --nl PROPUPD_WARN | |
| fi | |
| @@ -10964,7 +10967,7 @@ | |
| FILE_IS_PKGD=1 | |
| - PKGNAME=`echo "${PKGNAME_ARCH}" | egrep '\.(x86_64|ia64)$' 2>/dev/null | tail ${TAIL_OPT}1` | |
| + PKGNAME=`echo "${PKGNAME_ARCH}" | grep -E '\.(x86_64|ia64)$' 2>/dev/null | tail ${TAIL_OPT}1` | |
| test -z "${PKGNAME}" && PKGNAME=`echo "${PKGNAME_ARCH}" | tail ${TAIL_OPT}1` | |
| @@ -11163,7 +11166,7 @@ | |
| if [ -n "${PKGNAME}" -a -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then | |
| FNGREP=`echo "${FNAMEGREP}" | sed -e 's:^/::'` | |
| - SYSHASH=`egrep "( |\./)${FNGREP}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" | cut -d' ' -f1` | |
| + SYSHASH=`grep -E "( |\./)${FNGREP}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" | cut -d' ' -f1` | |
| if [ -n "${SYSHASH}" ]; then | |
| FILE_IS_PKGD=1 | |
| @@ -11172,7 +11175,7 @@ | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| - if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | egrep 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| + if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| @@ -11221,7 +11224,7 @@ | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| - if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | egrep 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| + if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| @@ -11252,7 +11255,7 @@ | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| - if [ -n "`${PKGMGR_SHA_HASH} "${FNAME}" 2>&1 | egrep 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| + if [ -n "`${PKGMGR_SHA_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| @@ -11295,7 +11298,7 @@ | |
| fi | |
| fi | |
| - if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | egrep '5|(^..\?)'`" ]; then | |
| + if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E '5|(^..\?)'`" ]; then | |
| HASH_TEST_PASSED=1 | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:hashchanged" | |
| @@ -11349,7 +11352,7 @@ | |
| SYSHASH=`${HASH_CMD} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ -z "${SYSHASH}" ]; then | |
| - if [ -n "`${HASH_CMD} "${FNAME}" 2>&1 | egrep 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| + if [ -n "`${HASH_CMD} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| if [ "${RKHHASH}" = "ignore-prelink-dep-err" ]; then | |
| SYSHASH="${RKHHASH}" | |
| display --to LOG --type INFO FILE_PROP_IGNORE_PRELINK_DEP_ERR "`name2text \"${FNAME}\"`" | |
| @@ -11445,7 +11448,7 @@ | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - echo "${PKGMGR_VERIFY_RESULT}" | egrep 'M|(^.\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:permchanged" | |
| + echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'M|(^.\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:permchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 2` | |
| @@ -11465,7 +11468,7 @@ | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - echo "${PKGMGR_VERIFY_RESULT}" | egrep 'U|(^.....\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:uidchanged" | |
| + echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'U|(^.....\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:uidchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 3` | |
| @@ -11485,7 +11488,7 @@ | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - echo "${PKGMGR_VERIFY_RESULT}" | egrep 'G|(^......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:gidchanged" | |
| + echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'G|(^......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:gidchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 4` | |
| @@ -11525,7 +11528,7 @@ | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | egrep 'S|(^\?)'`" ]; then | |
| + if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E 'S|(^\?)'`" ]; then | |
| SIZE_TEST_PASSED=1 | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:sizechanged" | |
| @@ -11553,7 +11556,7 @@ | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - echo "${PKGMGR_VERIFY_RESULT}" | egrep 'T|(^.......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:dtmchanged" | |
| + echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'T|(^.......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:dtmchanged" | |
| elif [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then | |
| RKH_CC2=`expr $RKH_CC + 6` | |
| @@ -11574,7 +11577,7 @@ | |
| if [ -h "${FNAME}" ]; then | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| - if [ -n "`echo \"${PKGMGR_VERIFY_RESULT}\" | egrep 'L|(^....\?)'`" ]; then | |
| + if [ -n "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E 'L|(^....\?)'`" ]; then | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| # Check the link target to see if it is whitelisted. | |
| @@ -11720,7 +11723,7 @@ | |
| RKHTMPVAR=`${LSATTR_CMD} "${FNAME}" 2>&1 | cut -d' ' -f1 | grep 'i'` | |
| fi | |
| else | |
| - RKHTMPVAR=`ls -lno "${FNAME}" 2>&1 | ${AWK_CMD} '{ print $5 }' | egrep 'uchg|schg|sappnd|uappnd|sunlnk|sunlink|schange|simmutable|sappend|uappend|uchange|uimmutable'` | |
| + RKHTMPVAR=`ls -lno "${FNAME}" 2>&1 | ${AWK_CMD} '{ print $5 }' | grep -E 'uchg|schg|sappnd|uappnd|sunlnk|sunlink|schange|simmutable|sappend|uappend|uchange|uimmutable'` | |
| fi | |
| # | |
| @@ -11768,9 +11771,9 @@ | |
| test -n "${BASENAME_CMD}" && RKHTMPVAR=`${BASENAME_CMD} "${FNAME}"` || RKHTMPVAR=`echo "${FNAME}" | sed -e 's:^.*/::'` | |
| if [ "${RKHTMPVAR}" = "rkhunter" ]; then | |
| - SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | egrep -i -v '(shell|/bin/sh) script( |,|$)'` | |
| + SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | grep -E -i -v '(shell|/bin/sh) script( |,|$)'` | |
| else | |
| - SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | egrep -i ' script( |,|$)'` | |
| + SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | grep -E -i ' script( |,|$)'` | |
| fi | |
| test -n "${SYSSCRIPT}" && TEST_RESULT="${TEST_RESULT} script" | |
| @@ -12256,7 +12259,7 @@ | |
| # Adding "text" to the egrep below widens scope at the expense of more false-positives and extending running time. | |
| # | |
| - if [ -n "`echo \"${FTYPE}\" | grep -v -i 'compres' | egrep -i 'execu|reloc|shell|libr|data|obj|text'`" ]; then | |
| + if [ -n "`echo \"${FTYPE}\" | grep -v -i 'compres' | grep -E -i 'execu|reloc|shell|libr|data|obj|text'`" ]; then | |
| FOUND=1 | |
| SUSPSCAN_NUM=1; SUSPSCAN_SCORE=0; SUSPSCAN_HITCOUNT=0 | |
| SUSPSCAN_STRINGS="" | |
| @@ -13151,7 +13154,7 @@ | |
| FOUND=0 | |
| if [ -n "${KSYMS_FILE}" ]; then | |
| - egrep -i 'adore|sebek' "${KSYMS_FILE}" >/dev/null 2>&1 && FOUND=1 | |
| + grep -E -i 'adore|sebek' "${KSYMS_FILE}" >/dev/null 2>&1 && FOUND=1 | |
| fi | |
| if [ $FOUND -eq 0 ]; then | |
| @@ -14061,7 +14064,7 @@ | |
| FNAMEGREP=`echo "${FNAMEGREP}" | sed -e 's/^|//;'` | |
| - if [ -n "`echo \"${FNAME}\" | egrep \"^(${FNAMEGREP})$\"`" ]; then | |
| + if [ -n "`echo \"${FNAME}\" | grep -E \"^(${FNAMEGREP})$\"`" ]; then | |
| PROCWHITELISTED=1 | |
| fi | |
| else | |
| @@ -14174,7 +14177,7 @@ | |
| RKHLSOF_FILE="${TEMPFILE}" | |
| touch "${RKHLSOF_FILE}" | |
| - ${LSOF_CMD} -wnlP +c 0 2>&1 | egrep -v ' (FIFO|V?DIR|IPv[46]) ' | sort | uniq >"${RKHLSOF_FILE}" | |
| + ${LSOF_CMD} -wnlP +c 0 2>&1 | grep -E -v ' (FIFO|V?DIR|IPv[46]) ' | sort | uniq >"${RKHLSOF_FILE}" | |
| # | |
| # Now loop through the known suspicious filenames, | |
| @@ -14376,7 +14379,7 @@ | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| SEEN=1 | |
| - FOUND_PROCS=`${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR} 2>&1 | egrep -v '^(Unhide |yjesus@|http:|Copyright |License |NOTE :|Used options:|\[\*\]|$)'` | |
| + FOUND_PROCS=`${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR} 2>&1 | grep -E -v '^(Unhide |yjesus@|http:|Copyright |License |NOTE :|Used options:|\[\*\]|$)'` | |
| if [ -z "${FOUND_PROCS}" ]; then | |
| # Nothing found. | |
| @@ -14957,7 +14960,7 @@ | |
| IFS=$IFSNL | |
| # Get the default enabled services. | |
| - for LINE in `egrep '^[ ]*enabled[ ]*\+?=' "${FILENAME}"`; do | |
| + for LINE in `grep -E '^[ ]*enabled[ ]*+?=' "${FILENAME}"`; do | |
| SEEN=1 | |
| RKHTMPVAR=`echo "${LINE}" | sed -e 's/^.*=//' | tr -s ' ' ' '` | |
| @@ -14975,7 +14978,7 @@ | |
| # Get the default disabled services. | |
| - for LINE in `egrep '^[ ]*disabled[ ]*\+?=' "${FILENAME}"`; do | |
| + for LINE in `grep -E '^[ ]*disabled[ ]*+?=' "${FILENAME}"`; do | |
| RKHTMPVAR=`echo "${LINE}" | sed -e 's/^.*=//' | tr -s ' ' ' '` | |
| XINETD_DFLTS_DISABLED="${XINETD_DFLTS_DISABLED} ${RKHTMPVAR}" | |
| @@ -15024,14 +15027,14 @@ | |
| # | |
| if [ -n "${XINETD_DFLTS_ENABLED}" ]; then | |
| - if [ -n "`echo \"${XINETD_DFLTS_ENABLED}\" | egrep \"${SVCID}\"`" ]; then | |
| - if [ -z "`echo \"${XINETD_DFLTS_DISABLED}\" | egrep \"${SVCID}\"`" ]; then | |
| + if [ -n "`echo \"${XINETD_DFLTS_ENABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| + if [ -z "`echo \"${XINETD_DFLTS_DISABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| SEEN=1 | |
| IFS=$IFSNL | |
| break | |
| fi | |
| fi | |
| - elif [ -n "`echo \"${XINETD_DFLTS_DISABLED}\" | egrep \"${SVCID}\"`" ]; then | |
| + elif [ -n "`echo \"${XINETD_DFLTS_DISABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| : | |
| elif [ -z "`echo $DATA | grep 'disable = yes'`" ]; then | |
| SEEN=1 | |
| @@ -15368,7 +15371,7 @@ | |
| test -f "${DIR}/mod_rootme2.so" && FOUNDFILES="${FOUNDFILES} ${DIR}/mod_rootme2.so" | |
| if [ -f "${DIR}/httpd.conf" ]; then | |
| - if [ -n "`egrep 'mod_rootme2?\.so' \"${DIR}/httpd.conf\"`" ]; then | |
| + if [ -n "`grep -E 'mod_rootme2?\.so' \"${DIR}/httpd.conf\"`" ]; then | |
| FOUNDFILES="${FOUNDFILES} ${DIR}/httpd.conf" | |
| fi | |
| fi | |
| @@ -15671,7 +15674,7 @@ | |
| ${FIND_CMD} "${LKM_PATH}" -type f -a \( -name "*.o" -o -name "*.ko" -o -name "*.ko.xz" \) >"${TEMPFILE}" 2>/dev/null | |
| for RKHTMPVAR in ${LKM_NAMES}; do | |
| - if [ -n "`egrep \"/${RKHTMPVAR}(\.xz)?$\" "${TEMPFILE}"`" ]; then | |
| + if [ -n "`grep -E \"/${RKHTMPVAR}(\.xz)?$\" "${TEMPFILE}"`" ]; then | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} ${RKHTMPVAR}" | |
| fi | |
| @@ -15821,10 +15824,10 @@ | |
| if [ -n "`echo \"${LSOFLINE}\" | grep \" ${PROTO} \*:${PORT} \"`" ]; then | |
| # Process listening for connections from anywhere. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| - elif [ -n "`echo \"${LSOFLINE}\" | egrep \" ${PROTO} [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:${PORT}[ -]\"`" ]; then | |
| + elif [ -n "`echo \"${LSOFLINE}\" | grep -E \" ${PROTO} [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:${PORT}[ -]\"`" ]; then | |
| # Established or listening process using IPv4 address. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| - elif [ -n "`echo \"${LSOFLINE}\" | egrep \" ${PROTO} \[[:0-9a-fA-F]+\]:${PORT}[ -]\"`" ]; then | |
| + elif [ -n "`echo \"${LSOFLINE}\" | grep -E \" ${PROTO} \[[:0-9a-fA-F]+\]:${PORT}[ -]\"`" ]; then | |
| # Established or listening process using IPv6 address. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| else | |
| @@ -15886,7 +15889,7 @@ | |
| if [ "${PROTO}" = "UDP" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | grep -i "^udp.*\.${PORT} " | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| elif [ "${PROTO}" = "TCP" ]; then | |
| - FOUND=`${NETSTAT_CMD} -an | egrep -i "^tcp.*\.${PORT} .*(BOUND|ESTABLISH|LISTEN)" | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| + FOUND=`${NETSTAT_CMD} -an | grep -E -i "^tcp.*\.${PORT} .*(BOUND|ESTABLISH|LISTEN)" | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| fi | |
| ;; | |
| SunOS) | |
| @@ -15897,10 +15900,10 @@ | |
| FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^UDP: IPv6/, /^$/ { print $1 }' | grep "\.${PORT}$"` | |
| fi | |
| elif [ "${PROTO}" = "TCP" ]; then | |
| - FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv4/, /^$/ { print $0 }' | egrep 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| + FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv4/, /^$/ { print $0 }' | grep -E 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| if [ -z "${FOUND}" ]; then | |
| - FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv6/, /^$/ { print $0 }' | egrep 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| + FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv6/, /^$/ { print $0 }' | grep -E 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| fi | |
| fi | |
| ;; | |
| @@ -16435,7 +16438,7 @@ | |
| WHITEPROC="" | |
| BLACKPROC="" | |
| - LIBPCAPRES=`egrep -v '(^sk | 888e )' /proc/net/packet 2>/dev/null | head ${HEAD_OPT}1` | |
| + LIBPCAPRES=`grep -E -v '(^sk | 888e )' /proc/net/packet 2>/dev/null | head ${HEAD_OPT}1` | |
| if [ -n "${LIBPCAPRES}" ]; then | |
| ALLOWPROCLISTENERS="" | |
| @@ -16451,7 +16454,7 @@ | |
| INODE_LIST="" | |
| - for INODE in `egrep -v '(^sk | 888e )' /proc/net/packet | ${AWK_CMD} '{ print $9 }'`; do | |
| + for INODE in `grep -E -v '(^sk | 888e )' /proc/net/packet | ${AWK_CMD} '{ print $9 }'`; do | |
| INODE_LIST="${INODE_LIST}|$INODE" | |
| done | |
| @@ -16459,7 +16462,7 @@ | |
| test -z "${INODE_LIST}" && INODE_LIST="RKHunterPktCapture" | |
| - for PID in `${LSOF_CMD} -lMnPw -d 1-20 2>/dev/null | egrep "[ ](pack[ ]+(${INODE_LIST})|sock[ ]+[^ ]+[ ]+[^ ]+[ ]+(${INODE_LIST}))[ ]" | ${AWK_CMD} '{ print $2 }'`; do | |
| + for PID in `${LSOF_CMD} -lMnPw -d 1-20 2>/dev/null | grep -E "[ ](pack[ ]+(${INODE_LIST})|sock[ ]+[^ ]+[ ]+[^ ]+[ ]+(${INODE_LIST}))[ ]" | ${AWK_CMD} '{ print $2 }'`; do | |
| NAME="" | |
| if [ -h "/proc/$PID/exe" -a $HAVE_READLINK -eq 1 ]; then | |
| @@ -16677,7 +16680,7 @@ | |
| RKHTMPVAR=`grep "${STRING}" "${FNAME}"` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| - test -z "`echo \"${RKHTMPVAR}\" | egrep -v '^[ ]*#'`" && continue | |
| + test -z "`echo \"${RKHTMPVAR}\" | grep -E -v '^[ ]*#'`" && continue | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:${STRING}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| @@ -16951,7 +16954,7 @@ | |
| if [ -n "${DSCL_CMD}" ]; then | |
| display --to LOG --type INFO FOUND_CMD 'dscl' "${DSCL_CMD}" | |
| - RKHTMPVAR2=`${DSCL_CMD} . search /Users uid 0 | egrep '^[^ )]' | cut -d' ' -f1` | |
| + RKHTMPVAR2=`${DSCL_CMD} . search /Users uid 0 | grep -E '^[^ )]' | cut -d' ' -f1` | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'dscl' | |
| fi | |
| @@ -17526,7 +17529,7 @@ | |
| test $SUNOS -eq 1 -o $IRIXOS -eq 1 && PS_ARGS="-ef" | |
| - RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep '(syslogd|syslog-ng)( |$)' | grep -v 'egrep'` | |
| + RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E '(syslogd|syslog-ng)( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SYSLOG_SEEN=1 | |
| @@ -17546,7 +17549,7 @@ | |
| TITLE_SHOWN=1 | |
| fi | |
| - RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep 'systemd-journald( |$)' | grep -v 'egrep'` | |
| + RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'systemd-journald( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SYSTEMD_SEEN=1 | |
| @@ -17562,7 +17565,7 @@ | |
| TITLE_SHOWN=1 | |
| fi | |
| - RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep 'metalog( |$)' | grep -v 'egrep'` | |
| + RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'metalog( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| METALOG_SEEN=1 | |
| @@ -17578,7 +17581,7 @@ | |
| TITLE_SHOWN=1 | |
| fi | |
| - RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep 'socklog( |$)' | grep -v 'egrep'` | |
| + RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'socklog( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SOCKLOG_SEEN=1 | |
| @@ -17639,7 +17642,7 @@ | |
| RKHTMPVAR="an" | |
| elif [ -n "`echo \"${FNAME}\" | grep '/syslog-ng\.conf$'`" ]; then | |
| FTYPE="syslog-ng" | |
| - elif [ -n "`echo \"${FNAME}\" | egrep '/(systemd-)?journald\.conf$'`" ]; then | |
| + elif [ -n "`echo \"${FNAME}\" | grep -E '/(systemd-)?journald\.conf$'`" ]; then | |
| FTYPE="systemd" | |
| else | |
| FTYPE="syslog" | |
| @@ -17657,15 +17660,15 @@ | |
| if [ "${FTYPE}" != "systemd" ]; then | |
| RKHTMPVAR="" | |
| - if [ -n "`echo \"${FNAME}\" | egrep '/r?syslog\.conf$'`" ]; then | |
| - RKHTMPVAR=`egrep -i '^[^#].*[ ](@|:omrelp:).' "${FNAME}" | egrep -i -v '(@|:omrelp:)127\.'` | |
| + if [ -n "`echo \"${FNAME}\" | grep -E '/r?syslog\.conf$'`" ]; then | |
| + RKHTMPVAR=`grep -E -i '^[^#].*[ ](@|:omrelp:).' "${FNAME}" | grep -E -i -v '(@|:omrelp:)127\.'` | |
| else | |
| # | |
| # For syslog-ng we must look for a destination | |
| # block which uses TCP or UDP. | |
| # | |
| - RKHTMPVAR=`${AWK_CMD} '/^[ ]*destination( | |$)/, /}/ { print $0 }' "${FNAME}" | egrep -i '( | |\{|^)(tcp|udp)6?( | |\(|$)' | egrep -v -i '(tcp|udp)6?[ ]*\([ ]*("[ ]*)?127\.'` | |
| + RKHTMPVAR=`${AWK_CMD} '/^[ ]*destination( | |$)/, /}/ { print $0 }' "${FNAME}" | grep -E -i '( | |\{|^)(tcp|udp)6?( | |\(|$)' | grep -E -v -i '(tcp|udp)6?[ ]*\([ ]*("[ ]*)?127\.'` | |
| fi | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| @@ -17681,7 +17684,7 @@ | |
| # that the warnings are shown before anything else. | |
| # | |
| - if [ $SYSLOG_SEEN -eq 1 -a -z "`echo \"${FILEFOUND}\" | egrep ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| + if [ $SYSLOG_SEEN -eq 1 -a -z "`echo \"${FILEFOUND}\" | grep -E ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NO_FILE 'syslog' | |
| elif [ $SYSTEMD_SEEN -eq 1 -a -z "`echo \"${FILEFOUND}\" | grep ' systemd '`" ]; then | |
| @@ -17697,7 +17700,7 @@ | |
| # We only display the remote logging result if a configuration file was found. | |
| # | |
| - if [ -n "`echo \"${FILEFOUND}\" | egrep ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| + if [ -n "`echo \"${FILEFOUND}\" | grep -E ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| if [ $ALLOW_SYSLOG_REMOTE_LOGGING -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE | |
| elif [ $REM_LOGGING_FOUND -eq 0 ]; then | |
| @@ -17734,7 +17737,7 @@ | |
| FTYPE=`echo "${FTYPE}" | tail ${TAIL_OPT}1` | |
| fi | |
| - if [ -z "`echo \"${FTYPE}\" | egrep -v '(character special|block special|socket|fifo \(named pipe\)|symbolic link to|empty|directory|/MAKEDEV:)'`" ]; then | |
| + if [ -z "`echo \"${FTYPE}\" | grep -E -v '(character special|block special|socket|fifo \(named pipe\)|symbolic link to|empty|directory|/MAKEDEV:)'`" ]; then | |
| return | |
| fi | |
| @@ -17832,7 +17835,7 @@ | |
| RKHTMPVAR=`find_cmd mount` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| - test -n "`${RKHTMPVAR} 2>/dev/null | egrep '^fdesc(fs)? .*(type fdesc|\(fdescfs\))'`" && FDESCFS=1 | |
| + test -n "`${RKHTMPVAR} 2>/dev/null | grep -E '^fdesc(fs)? .*(type fdesc|\(fdescfs\))'`" && FDESCFS=1 | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'mount' | |
| fi | |
| @@ -17930,7 +17933,7 @@ | |
| for DIR in ${SHORTSEARCHDIRS}; do | |
| if [ -d "${DIR}" ]; then | |
| - RKHTMPVAR=`ls -1d ${DIR}/.* 2>/dev/null | egrep -v '/\.\.?$'` | |
| + RKHTMPVAR=`ls -1d ${DIR}/.* 2>/dev/null | grep -E -v '/\.\.?$'` | |
| test -n "${RKHTMPVAR}" && LOOKINDIRS="${LOOKINDIRS} | |
| ${RKHTMPVAR}" | |
| fi | |
| @@ -17972,7 +17975,7 @@ | |
| FTYPE=`${FILE_CMD} "${FNAME}" 2>&1 | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| - test -n "`echo \"${FTYPE}\" | egrep 'character special|block special|empty'`" && continue | |
| + test -n "`echo \"${FTYPE}\" | grep -E 'character special|block special|empty'`" && continue | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| @@ -18313,7 +18316,7 @@ | |
| ;; | |
| named) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null` | |
| - VERSION=`echo "${WHOLE_VERSION}" | egrep '^(named|BIND)[ ][ ]*[0-9]' | grep -v '/' | ${AWK_CMD} '{ print $2 }'` | |
| + VERSION=`echo "${WHOLE_VERSION}" | grep -E '^(named|BIND)[ ][ ]*[0-9]' | grep -v '/' | ${AWK_CMD} '{ print $2 }'` | |
| if [ -n "`echo \"${VERSION}\" | grep '^[^-]*\.[0-9][0-9]*-P[^-]*-'`" ]; then | |
| VERSION=`echo "${VERSION}" | cut -d'-' -f1-2` | |
| @@ -18377,7 +18380,7 @@ | |
| if [ -n "`echo \"${APP_WHITELIST}\" | grep -i \" ${APPLICATION}:${RKHTMPVAR} \"`" ]; then | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%${VERSION}%-1" | |
| - elif [ -n "`egrep -i \"^${APPLICATION}:.* ${RKHTMPVAR}( |$)\" \"${DB_PATH}/programs_bad.dat\" 2>&1`" ]; then | |
| + elif [ -n "`grep -E -i \"^${APPLICATION}:.* ${RKHTMPVAR}( |$)\" \"${DB_PATH}/programs_bad.dat\" 2>&1`" ]; then | |
| APPS_FAILED_COUNT=`expr ${APPS_FAILED_COUNT} + 1` | |
| APP_RESULTS="${APP_RESULTS} | |
| @@ -19793,8 +19796,8 @@ | |
| # required commands are tested early on using just the root PATH. Then | |
| # BINDIR is checked, and finally the rest of the commands are then | |
| # checked using the new PATH from BINDIR. | |
| -ABSOLUTELY_REQUIRED_CMDS="cut egrep grep sed tail tr" | |
| -REQCMDS="awk cat chmod chown cp cut date egrep grep head ls mv sed sort tail touch tr uname uniq wc" | |
| +ABSOLUTELY_REQUIRED_CMDS="cut grep sed tail tr" | |
| +REQCMDS="awk cat chmod chown cp cut date grep head ls mv sed sort tail touch tr uname uniq wc" | |
| # This will be set to a list of commands that have been disabled. | |
| DISABLED_CMDS="" | |
| @@ -20904,10 +20907,10 @@ | |
| # | |
| if [ -z "${PRELINK_HASH}" ]; then | |
| - if [ -z "`echo \"${HASH_FUNC}\" | egrep '(/filehashsha\.pl Digest::MD5|/filehashsha\.pl .* 1$|shasum -a 1$)'`" ]; then | |
| + if [ -z "`echo \"${HASH_FUNC}\" | grep -E '(/filehashsha\.pl Digest::MD5|/filehashsha\.pl .* 1$|shasum -a 1$)'`" ]; then | |
| RKHTMPVAR=`echo "${HASH_FUNC}" | cut -d' ' -f1` | |
| - if [ -z "`echo ${RKHTMPVAR} | egrep -i 'sha1|md5'`" ]; then | |
| + if [ -z "`echo ${RKHTMPVAR} | grep -E -i 'sha1|md5'`" ]; then | |
| if [ $HASH_OPT -eq 1 ]; then | |
| echo "This system uses prelinking, but the '--hash' option (${HASH_FUNC}) does not look like SHA1 or MD5." | |
| else | |
| @@ -21015,7 +21018,7 @@ | |
| # | |
| IFS=$IFSNL | |
| -for LINE in `egrep '^MSG_(TYPE|RESULT)_' "${DB_PATH}/i18n/en" 2>/dev/null`; do | |
| +for LINE in `grep -E '^MSG_(TYPE|RESULT)_' "${DB_PATH}/i18n/en" 2>/dev/null`; do | |
| TYPE=`echo "${LINE}" | cut -d: -f1` | |
| if [ "${LANGUAGE}" != "en" ]; then | |
| @@ -21220,7 +21223,7 @@ | |
| fi | |
| elif [ -n "${PRELINK_HASH}" ]; then | |
| display --to LOG --type INFO HASH_FUNC_PRELINK "${PRELINK_HASH}" | |
| - elif [ -z "`echo \"${HASH_FUNC}\" | egrep -i 'sha1|md5'`" ]; then | |
| + elif [ -z "`echo \"${HASH_FUNC}\" | grep -E -i 'sha1|md5'`" ]; then | |
| SKIP_HASH_MSG=1 | |
| else | |
| display --to LOG --type INFO HASH_FUNC "${HASH_FUNC}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # This is PATCHED version of rkhunter 1.4.6-2 to eliminate grep and egrep warnings. | |
| # Diff vs the original: https://github.com/amekusa/arch-setup/compare/825d7ac..b2aceeb | |
| # | |
| # rkhunter -- Scan the system for rootkits and other known security issues. | |
| # | |
| # Copyright (c) 2003-2017, Michael Boelen ( michael AT rootkit DOT nl ) | |
| # | |
| # This program is free software; you can redistribute it and/or modify | |
| # it under the terms of the GNU General Public License as published by | |
| # the Free Software Foundation; either version 2 of the License, or | |
| # (at your option) any later version. | |
| # | |
| # This program is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| # GNU General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU General Public License | |
| # along with this program; if not, write to the Free Software | |
| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. | |
| # | |
| # | |
| # Unfortunately we must do some O/S checks at the very beginning, | |
| # otherwise SunOS will complain about some of the ksh/bash syntax. | |
| # By default the SunOS root account uses a simple Bourne shell, | |
| # which does not work with RKH. So we exec to use the Bash shell | |
| # if it is present, or the Korn shell which is usually installed | |
| # by default on Solaris systems. | |
| # | |
| BSDOS=0 | |
| SUNOS=0 | |
| BUSYBOX=0 | |
| OPERATING_SYSTEM=`uname 2>/dev/null` | |
| case "${OPERATING_SYSTEM}" in | |
| *BSD|DragonFly) | |
| BSDOS=1 | |
| unset CLICOLOR CLICOLOR_FORCE | |
| ;; | |
| SunOS) | |
| SUNOS=1 | |
| unset CLICOLOR CLICOLOR_FORCE | |
| ;; | |
| esac | |
| if [ $SUNOS -eq 1 ]; then | |
| # Simple SunOS test of RANDOM to see if we are now running bash or ksh. | |
| if [ -z "$RANDOM" ]; then | |
| # If the 'which' output contains a space, then it is probably an error. | |
| if [ -n "`which bash 2>/dev/null | grep -v ' '`" ]; then | |
| exec bash $0 $* | |
| elif [ -n "`which ksh 2>/dev/null | grep -v ' '`" ]; then | |
| exec ksh $0 $* | |
| else | |
| echo "Unable to find the bash or ksh shell to run rkhunter." | |
| exit 1 | |
| fi | |
| exit 0 | |
| fi | |
| fi | |
| # | |
| # Check to see if we are using the '--debug' option. If so, then | |
| # we exec to log everything to the debug file. | |
| # | |
| if [ -n "`echo \"$*\" | grep -- '--debug'`" ]; then | |
| RKHDEBUGFILE="" | |
| RKHDEBUGBASE="/tmp/rkhunter-debug" | |
| # | |
| # Ensure we create a random file name. | |
| # | |
| if [ -n "`which mktemp 2>/dev/null | grep -v ' '`" ]; then | |
| RKHDEBUGFILE=`mktemp ${RKHDEBUGBASE}.XXXXXXXXXX` | |
| elif [ -n "$RANDOM" ]; then | |
| RKHDEBUGFILE="${RKHDEBUGBASE}.$RANDOM" | |
| elif [ -n "`date +%N%s 2>/dev/null | grep '^[0-9][0-9]*$'`" ]; then | |
| RKHDEBUGFILE="${RKHDEBUGBASE}.`date +%N%s%N`" | |
| elif [ -n "`date +%Y%m%d%H%M%S 2>/dev/null | grep '^[0-9][0-9]*$'`" ]; then | |
| RKHDEBUGFILE="${RKHDEBUGBASE}.`date +%Y%m%d%H%M%S`" | |
| else | |
| RKHDEBUGFILE="${RKHDEBUGBASE}.$$" | |
| fi | |
| if [ -e "${RKHDEBUGFILE}" ]; then | |
| if [ -f "${RKHDEBUGFILE}" -a ! -h "${RKHDEBUGFILE}" ]; then | |
| rm -f "${RKHDEBUGFILE}" >/dev/null 2>&1 | |
| else | |
| echo "Cannot use '--debug' option. Debug file \"${RKHDEBUGFILE}\" already exists, but it is not a file." | |
| exit 1 | |
| fi | |
| fi | |
| DEBUG_OPT=1 | |
| exec 1>"${RKHDEBUGFILE}" 2>&1 | |
| chmod 600 "${RKHDEBUGFILE}" >/dev/null 2>&1 | |
| set -x | |
| else | |
| DEBUG_OPT=0 | |
| fi | |
| # | |
| # Now we must determine if we are using the Korn shell or not. If so, | |
| # then we alias the 'echo' command and set ECHOOPT. For other shells, | |
| # we try and determine the real shell being used, and test to see if | |
| # the 'echo -e' command is valid or not. We set ECHOOPT accordingly. | |
| # | |
| # | |
| # Unfortunately *BSD doesn't seem to allow capturing of unknown commands. | |
| # So we must alias 'print' to something valid, but which will fail. | |
| # | |
| test $BSDOS -eq 1 && alias print=false | |
| if [ "`print "rkh-ksh-string-test" 2>/dev/null`" = "rkh-ksh-string-test" ]; then | |
| alias echo='print' | |
| ECHOOPT="--" | |
| MYSHELL=ksh | |
| elif [ $SUNOS -eq 1 ]; then | |
| # For Solaris, if we are not running ksh, then it must be bash. | |
| MYSHELL=bash | |
| ECHOOPT="-e" | |
| else | |
| # | |
| # We want to get the actual shell used by this program, and | |
| # so we need to test /bin/sh. | |
| # | |
| MYSHELL=/bin/sh | |
| test -h ${MYSHELL} && MYSHELL=`readlink ${MYSHELL} 2>/dev/null` | |
| MYSHELL=`basename ${MYSHELL} 2>/dev/null` | |
| # Assume 'bash' if we have problems finding the real shell. | |
| test -z "${MYSHELL}" && MYSHELL=bash | |
| # Check if we are using BusyBox. | |
| test "${MYSHELL}" = "busybox" && BUSYBOX=1 | |
| # | |
| # Now test the 'echo -e' command. | |
| # | |
| if [ "`echo -e \"rkh-ksh\tstring-test\" 2>/dev/null`" = "rkh-ksh string-test" ]; then | |
| ECHOOPT="-e" | |
| else | |
| ECHOOPT="" | |
| fi | |
| fi | |
| # | |
| # We now perform a similar test to see if 'echo -n', or "\c", is valid | |
| # or not. Unfortunately on some systems both '-e' and '-n' are valid, | |
| # but not together. The "\c" option works in these cases. So we set | |
| # ECHON accordingly. | |
| # | |
| if [ "`echo -n -e \"rkh-ksh-string-test\" 2>/dev/null`" = "rkh-ksh-string-test" ]; then | |
| ECHON="-n" | |
| elif [ "`echo -e \"rkh-ksh-string-test\c\" 2>/dev/null`" = "rkh-ksh-string-test" ]; then | |
| ECHON="c" | |
| elif [ "`echo \"rkh-ksh-string-test\c\" 2>/dev/null`" = "rkh-ksh-string-test" ]; then | |
| ECHON="c" | |
| else | |
| ECHON="" | |
| fi | |
| # | |
| # We also need to run a test to see if POSIX grep is being | |
| # used. If it is, then some typical grep tests will fail. | |
| # | |
| if [ "`echo \"rkh-grep-test\" | grep '^+'`" = "rkh-grep-test" ]; then | |
| alias grep='grep -E' | |
| fi | |
| # | |
| # It seems that the BusyBox 'readlink' command does have | |
| # a '-f' option, but it does not show the true pathname. | |
| # So we only use the option for everyone else. | |
| # | |
| test $BUSYBOX -eq 1 && READLINK_OPT="" || READLINK_OPT="-f" | |
| # | |
| # Finally, we need to test the 'head' and 'tail' commands | |
| # to see if they understand the '-n' option or not. | |
| # | |
| if head -n 1 </dev/null >/dev/null 2>&1; then | |
| HEAD_OPT="-n " | |
| else | |
| HEAD_OPT="-" | |
| fi | |
| if tail -n 1 </dev/null >/dev/null 2>&1; then | |
| TAIL_OPT="-n " | |
| else | |
| TAIL_OPT="-" | |
| fi | |
| ###################################################################### | |
| # | |
| # Global function definitions | |
| # | |
| ###################################################################### | |
| display() { | |
| # | |
| # This function is used to display text messages on to the | |
| # users screen, as well as in to the log file. The same | |
| # message is written to both. However, the screen may have | |
| # a coloured result (green for good, red for bad, etc), and | |
| # the log file will have the time prefixed to the message and, | |
| # optionally, additional information messages after the main | |
| # message. All the messages are indexed in the language file. | |
| # | |
| # Syntax: display --to <destination> --type <type> | |
| # [--screen-indent <n>] [--log-indent <n>] | |
| # [--nl [<n>]] [--nl-after] [--log-nl] [--screen-nl] [--nonl] | |
| # [--result <result> --color <colour>] | |
| # <message index> [optional message arguments] | |
| # | |
| # where the destination can be one of SCREEN, LOG or SCREEN+LOG. | |
| # The type can be one of PLAIN, INFO or WARNING. | |
| # The language file will have all the current values. | |
| # | |
| # The --screen-indent and --log-indent options are used to | |
| # forcibly indent a message. | |
| # The --nl option causes a blank-line to be output before the | |
| # message both on the screen and in the log file. A following | |
| # number can be used to indicate how many blank lines should | |
| # be displayed on the screen. | |
| # The --log-nl option outputs a blank line only in the log file. | |
| # The --screen-nl option outputs a blank line on the screen | |
| # regardless of whether SCREEN was specified or not. | |
| # The --nl-after option outputs a blank line on the screen after | |
| # the message. | |
| # The --nonl option is only to be used in special cases where we | |
| # want the output of more than one message to appear on the same | |
| # line. This is currently only used when trying to obtain the | |
| # lock file. It only applies to PLAIN messages, and may not be | |
| # supported on all systems (depending on whether 'echo -n' works | |
| # or not). | |
| # | |
| # | |
| # We first initialize some variables and then | |
| # process the switches used. | |
| # | |
| WARN_MSG=0; NL=0; NLAFTER=0; LOGINDENT=0; SCREENINDENT=0 | |
| LOGNL=0; SCREENNL=0 | |
| WRITETO=''; TYPE=''; RESULT=''; COLOR=''; MSG='' | |
| LINE1=''; LOGLINE1=''; SPACES=''; NONL='' | |
| # | |
| # The IFS environment variable could be set to a non-default value | |
| # when this function is called. However, we need it to be the default | |
| # value in order to dislay things correctly. So, we record the initial | |
| # value, and then set it to the default. We set it back to the initial | |
| # value whenever we return from this function. | |
| # | |
| ORIG_IFS=$IFS | |
| IFS=$RKHIFS | |
| DISPLAY_LINE="display $*" | |
| if [ $# -le 0 ]; then | |
| echo "Error: Invalid display call - no arguments given" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| while [ $# -ge 1 ]; do | |
| case "$1" in | |
| --to) | |
| case "$2" in | |
| SCREEN|LOG|SCREEN+LOG) | |
| WRITETO=$2 | |
| ;; | |
| *) | |
| echo "Error: Invalid display destination: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| ;; | |
| esac | |
| shift | |
| ;; | |
| --type) | |
| TYPE=`eval echo "\\$MSG_TYPE_$2"` | |
| if [ -z "${TYPE}" -a "$2" != "PLAIN" ]; then | |
| if [ $RKHLANGUPDT -eq 0 ]; then | |
| echo "Error: Invalid display type: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| fi | |
| test "$2" = "WARNING" && WARN_MSG=1 | |
| shift | |
| ;; | |
| --result) | |
| RESULT=`eval echo "\\$MSG_RESULT_$2"` | |
| if [ -z "${RESULT}" ]; then | |
| if [ $RKHLANGUPDT -eq 0 ]; then | |
| echo "Error: Invalid display result: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| fi | |
| shift | |
| ;; | |
| --color) | |
| if [ $COLORS -eq 1 ]; then | |
| test -n "$2" && COLOR=`eval "echo \\${$2}"` | |
| if [ -z "${COLOR}" ]; then | |
| echo "Error: Invalid display color: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| fi | |
| shift | |
| ;; | |
| --log-indent) | |
| LOGINDENT=$2 | |
| if [ -z "${LOGINDENT}" ]; then | |
| echo "Error: No --log-indent value given. Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| elif [ -z "`echo ${LOGINDENT} | grep '^[0-9]*$'`" ]; then | |
| echo "Error: Invalid '--log-indent' value given: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| shift | |
| ;; | |
| --screen-indent) | |
| SCREENINDENT=$2 | |
| if [ -z "${SCREENINDENT}" ]; then | |
| echo "Error: No --screen-indent value given. Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| elif [ -z "`echo ${SCREENINDENT} | grep '^[0-9]*$'`" ]; then | |
| echo "Error: Invalid '--screen-indent' value given: $2 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| shift | |
| ;; | |
| --nl) | |
| NL=1 | |
| case "$2" in | |
| [0-9]) | |
| NL=$2 | |
| shift | |
| ;; | |
| esac | |
| ;; | |
| --log-nl) | |
| LOGNL=1 | |
| ;; | |
| --screen-nl) | |
| SCREENNL=1 | |
| ;; | |
| --nl-after) | |
| NLAFTER=1 | |
| ;; | |
| --nonl) | |
| NONL=$ECHON | |
| ;; | |
| -*) | |
| echo "Error: Invalid display option given: $1 Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| ;; | |
| *) | |
| MSG=$1 | |
| shift | |
| break | |
| ;; | |
| esac | |
| shift | |
| done | |
| # | |
| # Before anything we must record if this is a warning message. | |
| # | |
| test $WARN_MSG -eq 1 && WARNING_COUNT=`expr ${WARNING_COUNT} + 1` | |
| # | |
| # For simplicity we now set variables as to whether the output | |
| # goes to the screen and/or the log file. In some cases we do | |
| # not need to output anything, and so can just return. | |
| # | |
| if [ $NOLOG -eq 1 ]; then | |
| if [ "${WRITETO}" = "LOG" ]; then | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| test "${WRITETO}" = "SCREEN+LOG" && WRITETO="SCREEN" | |
| fi | |
| if [ $NOTTY -eq 1 ]; then | |
| if [ "${WRITETO}" = "SCREEN" ]; then | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| test "${WRITETO}" = "SCREEN+LOG" && WRITETO="LOG" | |
| fi | |
| test "${WRITETO}" = "SCREEN" -o "${WRITETO}" = "SCREEN+LOG" && WRITETOTTY=1 || WRITETOTTY=0 | |
| test "${WRITETO}" = "LOG" -o "${WRITETO}" = "SCREEN+LOG" && WRITETOLOG=1 || WRITETOLOG=0 | |
| # | |
| # Now check that the options we have been given make sense. | |
| # | |
| if [ $WRITETOTTY -eq 0 -a $WRITETOLOG -eq 0 ]; then | |
| echo "Error: Invalid display destination: Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| elif [ $WRITETOTTY -eq 1 -a $COLORS -eq 1 -a -n "${RESULT}" -a -z "${COLOR}" ]; then | |
| echo "Error: Invalid display - no color given: Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| # | |
| # We only allow no newline for PLAIN messages. | |
| # | |
| test -n "${TYPE}" && NONL="" | |
| # | |
| # If we want whitelisted results to be shown as white, or | |
| # black for colour set two users, then change the colour now. | |
| # | |
| if [ $WLIST_IS_WHITE -eq 1 -a $WRITETOTTY -eq 1 -a $COLORS -eq 1 -a "${RESULT}" = "${MSG_RESULT_WHITELISTED}" ]; then | |
| COLOR=$WHITE | |
| fi | |
| # | |
| # We set the variable LINE1 to contain the first line of the message. | |
| # For the log file we use the variable LOGLINE1. We also set | |
| # where the language file is located. If a message cannot be found | |
| # in the file, then we look in the English file. This will allow RKH | |
| # to still work even when the language files change. | |
| # | |
| LANG_FILE="${DB_PATH}/i18n/${LANGUAGE}" | |
| if [ -n "${MSG}" ]; then | |
| LINE1=`grep ${GREP_OPT} "^${MSG}:" "${LANG_FILE}" 2>/dev/null | head ${HEAD_OPT}1 | cut -d: -f2-` | |
| if [ $RKHCHKLOCALE -eq 1 ]; then | |
| LINE1=`echo "${LINE1}" | ${ICONV_CMD} -f UTF-8 -t ${RKHCHRMAP} 2>/dev/null` | |
| test $? -ne 0 && LINE1="" | |
| fi | |
| if [ -z "${LINE1}" ]; then | |
| LANG_FILE="${DB_PATH}/i18n/en" | |
| LINE1=`grep ${GREP_OPT} "^${MSG}:" "${LANG_FILE}" 2>/dev/null | head ${HEAD_OPT}1 | cut -d: -f2-` | |
| if [ -z "${LINE1}" ]; then | |
| echo "Error: Invalid display - keyword cannot be found: Display line: ${DISPLAY_LINE}" | |
| IFS=$ORIG_IFS | |
| return | |
| fi | |
| else | |
| LINE1=`echo "${LINE1}" | sed -e 's/\`/\\\\\`/g'` | |
| fi | |
| test -n "${LINE1}" && LINE1=`eval "echo \"${LINE1}\" | sed -e 's/;/\\;/g'"` | |
| fi | |
| # | |
| # At this point LINE1 is the text of the message. We have to | |
| # see if the message is to be indented, and must prefix the | |
| # time to log file messages. We must do the log file first | |
| # because it uses LINE1. | |
| # | |
| if [ $WRITETOLOG -eq 1 ]; then | |
| LOGLINE1=`date '+[%H:%M:%S]'` | |
| test $NL -gt 0 -o $LOGNL -eq 1 && echo "${LOGLINE1}" >>"${RKHLOGFILE}" | |
| if [ -n "${TYPE}" ]; then | |
| LOGLINE1="${LOGLINE1} ${TYPE}: ${LINE1}" | |
| else | |
| test $LOGINDENT -gt 0 && SPACES=`echo "${BLANK_LINE}" | cut -c1-$LOGINDENT` | |
| LOGLINE1="${LOGLINE1} ${SPACES}${LINE1}" | |
| fi | |
| fi | |
| if [ $WRITETOTTY -eq 1 -a $SCREENINDENT -gt 0 ]; then | |
| SPACES=`echo "${BLANK_LINE}" | cut -c1-$SCREENINDENT` | |
| LINE1="${SPACES}${LINE1}" | |
| fi | |
| # | |
| # We now check to see if a result is to be output. If it is, | |
| # then we need to space-out the line and color the result. | |
| # | |
| if [ -n "${RESULT}" ]; then | |
| if [ $WRITETOTTY -eq 1 ]; then | |
| LINE1_NUM=`echo "${LINE1}" | wc -c | tr -d ' '` | |
| NUM_SPACES=`expr 62 - ${LINE1_NUM}` | |
| test $NUM_SPACES -lt 1 && NUM_SPACES=1 | |
| if [ $COLORS -eq 0 ]; then | |
| SPACES=`echo "${BLANK_LINE}" | cut -c1-$NUM_SPACES` | |
| LINE1="${LINE1}${SPACES}[ ${RESULT} ]" | |
| else | |
| LINE1="${LINE1}\033[${NUM_SPACES}C[ ${COLOR}${RESULT}${NORMAL} ]" | |
| fi | |
| fi | |
| if [ $WRITETOLOG -eq 1 ]; then | |
| LOGLINE1_NUM=`echo "${LOGLINE1}" | wc -c | tr -d ' '` | |
| NUM_SPACES=`expr 62 - ${LOGLINE1_NUM}` | |
| test $NUM_SPACES -lt 1 && NUM_SPACES=1 | |
| SPACES=`echo "${BLANK_LINE}" | cut -c1-$NUM_SPACES` | |
| LOGLINE1="${LOGLINE1}${SPACES}[ ${RESULT} ]" | |
| fi | |
| elif [ $WRITETOTTY -eq 1 -a -n "${COLOR}" ]; then | |
| LINE1="${COLOR}${LINE1}${NORMAL}" | |
| fi | |
| # | |
| # We can now output the message. We start with any required blank | |
| # lines, and then the first line. If this is a warning message we | |
| # write to the log file any additional lines. | |
| # | |
| if [ $SCREENNL -eq 1 ]; then | |
| test $QUIET -eq 0 -a $SHOWWARNINGSONLY -eq 0 -a $NOTTY -eq 0 && echo "" | |
| fi | |
| if [ $WRITETOTTY -eq 1 ]; then | |
| NLLOOP=$NL | |
| while test $NLLOOP -gt 0; do | |
| echo "" | |
| NLLOOP=`expr ${NLLOOP} - 1` | |
| done | |
| if [ "${NONL}" = "c" ]; then | |
| echo $ECHOOPT "${LINE1}\c" | |
| else | |
| echo $NONL $ECHOOPT "${LINE1}" | |
| fi | |
| fi | |
| if [ $WRITETOLOG -eq 1 ]; then | |
| echo $ECHOOPT "${LOGLINE1}" >>"${RKHLOGFILE}" | |
| if [ $WARN_MSG -eq 1 ]; then | |
| test $SHOWWARNINGSONLY -eq 1 && echo $ECHOOPT "${LOGLINE1}" | cut -d' ' -f2- | |
| LINE1=1 | |
| OLDIFS=$IFS | |
| IFS=$IFSNL | |
| for LOGLINE1 in `grep ${GREP_OPT} "^${MSG}:" "${LANG_FILE}" 2>/dev/null | cut -d: -f2-`; do | |
| if [ $LINE1 -eq 1 ]; then | |
| LINE1=0 | |
| continue | |
| else | |
| test $SHOWWARNINGSONLY -eq 1 && echo $ECHOOPT " ${LOGLINE1}" | |
| echo $ECHOOPT " ${LOGLINE1}" >>"${RKHLOGFILE}" | |
| fi | |
| done | |
| IFS=$OLDIFS | |
| elif [ $SHOWWARNINGSONLY -eq 1 -a -n "`echo \"${LOGLINE1}\" | grep '^\[[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\] '`" ]; then | |
| echo $ECHOOPT "${LOGLINE1}" | cut -d' ' -f2- | |
| fi | |
| fi | |
| # | |
| # Output a final blank line if requested to do so. | |
| # | |
| test $WRITETOTTY -eq 1 -a $NLAFTER -eq 1 && echo "" | |
| IFS=$ORIG_IFS | |
| return | |
| } | |
| name2text() { | |
| # | |
| # This function changes any spaces in a character string to '<SP>', | |
| # tabs to '<TAB>' and any control characters to '?'. This allows | |
| # pathnames to be seen more easily - especially if spaces or tabs | |
| # are used. | |
| # | |
| # Whilst it would be nice to perform this function in 'display', we do | |
| # not want the changes to occur for all messages. So we keep this a | |
| # separate function, and only use it where necessary. | |
| # | |
| # Note that we must ensure that the 'echo' command does not interpret | |
| # any part of the string. | |
| # | |
| echo $ECHOOPT "$*" | sed -e 's/ /<SP>/g; s/ /<TAB>/g' | tr -d '\n' | tr '[:cntrl:]' '?' | |
| return | |
| } | |
| keypresspause() { | |
| # | |
| # This function will display a prompt message to the user. | |
| # | |
| if [ $SKIP_KEY_PRESS -eq 0 -a $QUIET -eq 0 ]; then | |
| display --to SCREEN --type PLAIN --nl PRESSENTER | |
| read RKHTMPVAR | |
| test "${RKHTMPVAR}" = "s" -o "${RKHTMPVAR}" = "S" && SKIP_KEY_PRESS=1 | |
| fi | |
| return | |
| } | |
| get_option() { | |
| # | |
| # This function is used to process configuration file options. | |
| # | |
| # Syntax: get_option (single | space-list | newline-list) <option name> | |
| # | |
| # The first parameter indicates if the option can occur on one | |
| # or more lines in the configuration files. A 'space-list' is a | |
| # space-separated list, and 'newline-list' is a newline-separated | |
| # list. These will both typically be multiline. The second parameter | |
| # is the configuration file option name. | |
| # | |
| # Single line options are typically numbers, a single word or pathname. | |
| # Multiline options are usually pathnames, and will be a space-separated | |
| # or newline-separated list. Space-separated lists are, obviously, not | |
| # expected to contain any special characters such as a space. | |
| # | |
| # The function will output the final, non-expanded, option value. | |
| # It will also return an error code. A code of zero indicates no | |
| # problem, but a code of one indicates an error. | |
| # | |
| OPTMULTI="$1" | |
| OPTNAME="$2" | |
| if [ -z "${OPTMULTI}" -o -z "${OPTNAME}" ]; then | |
| echo "Error: Missing arguments in get_option function: $*" >&2 | |
| return 1 | |
| fi | |
| # | |
| # First see if the option is in the configuration files. | |
| # | |
| RKHTMPVAR2=`grep -h "^${OPTNAME}=" ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES}` | |
| if [ -z "${RKHTMPVAR2}" ]; then | |
| echo "" | |
| return 0 | |
| fi | |
| # | |
| # We have an option, so process it. | |
| # | |
| case "${OPTMULTI}" in | |
| single) | |
| OPTVAR=`echo "${RKHTMPVAR2}" | tail ${TAIL_OPT}1 | sed -e "s/${OPTNAME}=//"` | |
| # If the option is unset, then just return. | |
| if [ -z "${OPTVAR}" -o "${OPTVAR}" = '""' -o "${OPTVAR}" = "''" ]; then | |
| echo "" | |
| return 0 | |
| fi | |
| # | |
| # We must handle any _CMD option specially because they may | |
| # contain quote characters, and we do not want to remove these. | |
| # | |
| case "${OPTNAME}" in | |
| *_CMD|WEBCMD|HASH_FUNC) | |
| ;; | |
| *_OPTS) | |
| # | |
| # Rkhunter configuration options which are command options may | |
| # begin with a hyphen ('-'). This can cause problems for the | |
| # 'echo' command. To prevent this, the simplest solution is to | |
| # append a space to the option value. | |
| # | |
| OPTVAR=`echo "${OPTVAR} " | tr -d '" ' | tr -d "'"` | |
| test -n "`echo \"${OPTVAR} \" | grep '^-'`" && OPTVAR="${OPTVAR} " | |
| ;; | |
| *) | |
| OPTVAR=`echo "${OPTVAR}" | tr -d '" ' | tr -d "'"` | |
| ;; | |
| esac | |
| ;; | |
| space-list|newline-list) | |
| # | |
| # We must test whether the last line is set to the null string because | |
| # a multiline option is reset by specifying the last setting as null. | |
| # | |
| RKHTMPVAR3=`echo "${RKHTMPVAR2}" | tail ${TAIL_OPT}1 | sed -e "s/${OPTNAME}=//"` | |
| # If the option is unset, then just return. | |
| if [ -z "${RKHTMPVAR3}" -o "${RKHTMPVAR3}" = '""' -o "${RKHTMPVAR3}" = "''" ]; then | |
| echo "" | |
| return 0 | |
| fi | |
| OPTVAR=`echo "${RKHTMPVAR2}" | sed -e "s/${OPTNAME}=//"` | |
| # | |
| # If an option begins with a hyphen, then this will cause problems | |
| # for the 'echo' command. So to prevent the problem we simply add | |
| # a space to the option value. We must repeat this though if the | |
| # variable is set again. | |
| # | |
| test -n "`echo \"${OPTVAR} \" | grep '^-'`" && OPTVAR="${OPTVAR} " | |
| # | |
| # Newline-separated list can contain virtually any character, so | |
| # we leave them alone. But for space-separated lists we can be nice | |
| # and compress spaces and remove quotes. | |
| # | |
| if [ "${OPTMULTI}" = "space-list" ]; then | |
| OPTVAR=`echo "${OPTVAR}" | tr -s ' ' ' '` | |
| OPTVAR=`echo "${OPTVAR}" | sed -e 's/^ *"* *//; s/ *"* *$//' | sed -e "s/^ *'* *//; s/ *'* *$//"` | |
| test -n "`echo \"${OPTVAR} \" | grep '^-'`" && OPTVAR="${OPTVAR} " | |
| # | |
| # We only use the options given after the last blank line (if any). | |
| # | |
| if [ -n "${OPTVAR}" ]; then | |
| RKHLINES=`echo "${OPTVAR}" | wc -l | tr -d ' '` | |
| OPTVAR=`echo "${OPTVAR}" | ${AWK_CMD} -v l="$RKHLINES" '/./ { if (a) { a = a "\n" $0 } else a = $0 }; /^$/ { a = "" }; NR == l { print a }'` | |
| test -n "`echo \"${OPTVAR} \" | grep '^-'`" && OPTVAR="${OPTVAR} " | |
| fi | |
| else | |
| # | |
| # For newline-separated lists, which will be pathnames, we are | |
| # nice to the user and will strip off a leading single or double | |
| # quote character *if* it also ends in the same quote character. | |
| # Since these should be pathnames they should start with the | |
| # '/' character. A quote as the first character implies that the | |
| # user has quoted the pathname. | |
| # | |
| if [ -n "`echo \"${OPTVAR}\" | grep '^\".*\"$'`" ]; then | |
| OPTVAR=`echo "${OPTVAR}" | sed -e 's/^"\(.*\)"$/\1/'` | |
| elif [ -n "`echo \"${OPTVAR}\" | grep \"^'.*'$\"`" ]; then | |
| OPTVAR=`echo "${OPTVAR}" | sed -e "s/^'\(.*\)'$/\1/"` | |
| fi | |
| fi | |
| ;; | |
| *) | |
| echo "Error: Invalid argument in get_option function: $*" >&2 | |
| return 1 | |
| ;; | |
| esac | |
| echo "${OPTVAR}" | |
| return 0 | |
| } | |
| check_paths() { | |
| # | |
| # This function will check a supplied list of pathnames to | |
| # ensure the files and directories exist. It will also | |
| # check that directories such as '/' (root) are not present, | |
| # nor are pathnames with unwanted characters. | |
| # | |
| # Syntax: check_paths <pathnames> <option_name> "[EXIST] [NOWILD] [NOBROKENLINK]" | |
| # | |
| # The function only checks the pathnames. It is not possible | |
| # to modify the list in any way. The variable ERRCODE will be | |
| # set to one if any pathname fails a check. | |
| # | |
| # The first parameter is the list of pathnames to check. The | |
| # second parameter is the option name to be used in the error | |
| # messages. The third parameter is a space-separated list | |
| # indicating how strict the checks need to be with respect to | |
| # the pathnames existence, whether wildcard characters are | |
| # allowed, and whether symbolic links are allowed. The | |
| # argument is a space-separated list of the words 'EXIST' | |
| # (meaning the pathname must exist), 'NOWILD' (meaning that | |
| # shell wildcard characters are not allowed), and 'NOBROKENLINK' | |
| # (meaning that the pathname must not be a broken link). | |
| # The words may be given in any order. | |
| # | |
| OPT_VALUE_OPT=$1 | |
| OPT_NAME=$2 | |
| STRICT=$3 | |
| test -z "${OPT_NAME}" && OPT_NAME=${OPT_VALUE_OPT} | |
| OPT_VALUE=`eval echo \"\\$${OPT_VALUE_OPT}\"` | |
| ERRCODE=0 | |
| MUSTEXIST=0 | |
| NOWILD=0 | |
| NOBROKENLINK=0 | |
| for RKHTMPVAR in ${STRICT}; do | |
| case "${RKHTMPVAR}" in | |
| EXIST) | |
| MUSTEXIST=1 | |
| ;; | |
| NOWILD) | |
| NOWILD=1 | |
| ;; | |
| NOBROKENLINK) | |
| NOBROKENLINK=1 | |
| ;; | |
| *) | |
| echo "Error: Invalid argument in check_paths function: $*" >&2 | |
| ;; | |
| esac | |
| done | |
| # | |
| # If no option value was given then just return (generally this situation | |
| # should never happen). However, if the file was required to exist, then | |
| # return with an error. | |
| # | |
| if [ -z "${OPT_VALUE}" ]; then | |
| if [ $MUSTEXIST -eq 1 ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: No filename given, but it must exist." | |
| fi | |
| return | |
| fi | |
| # | |
| # If a pathname begins with a hyphen, then this will cause problems | |
| # for the 'echo' command. Since we generally don't allow plain filenames, | |
| # as opposed to a pathname, and these won't begin with a hyphen, we can | |
| # test and reject these. | |
| # | |
| RKHTMPVAR=`echo "${OPT_VALUE} " | grep '^-'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| ERRCODE=1 | |
| # We need to get RKHTMPVAR into a single line now, but we can't use a | |
| # straight echo command here because that would expand any wildcards. | |
| RKHTMPVAR=`make_space_list "${RKHTMPVAR}"` | |
| echo "Invalid ${OPT_NAME} configuration option: Pathname begins with a hyphen: ${RKHTMPVAR}" | |
| return | |
| fi | |
| # | |
| # We must check the entry for wildcard characters first | |
| # because the following 'for' command will expand them. | |
| # | |
| if [ $NOWILD -eq 1 ]; then | |
| # | |
| # For the SHARED_LIB_WHITELIST option the pathname may contain | |
| # the '{}' characters (wrapped around variable names). So we do | |
| # not check for these characters for that particular option. | |
| # | |
| if [ "${OPT_NAME}" = "SHARED_LIB_WHITELIST" ]; then | |
| RKHTMPVAR=`echo "${OPT_VALUE}" | grep -E '(^|[^\\])[][?*]'` | |
| else | |
| RKHTMPVAR=`echo "${OPT_VALUE}" | grep -E '(^|[^\\])[][?*{}]'` | |
| fi | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| ERRCODE=1 | |
| # We need to get RKHTMPVAR into a single line now, but we can't use a | |
| # straight echo command here because that would expand the wildcards. | |
| RKHTMPVAR=`make_space_list "${RKHTMPVAR}"` | |
| echo "Invalid ${OPT_NAME} configuration option: Pathname contains wildcard characters: ${RKHTMPVAR}" | |
| return | |
| fi | |
| fi | |
| # | |
| # Now check each pathname in the option. | |
| # | |
| # If this is a newline list option then we need to read a line at a time. | |
| if [ -n "`echo \"${NEWLINE_LIST_OPTS}\" | grep \" ${OPT_NAME} \"`" ]; then | |
| IFS=$IFSNL | |
| fi | |
| for FNAME in ${OPT_VALUE}; do | |
| test -z "${FNAME}" && continue | |
| # | |
| # For some options we may have to remove the leading character. | |
| # | |
| # TODO: | |
| # This is no longer needed since we moved the check_paths for bindir paths. | |
| # The code is left here since we may need something very similar for overloaded options. | |
| # overloaded options - ALLOWPROCDELFILE PORT_PATH_WHITELIST RTKT_FILE_WHITELIST | |
| # if [ "${OPT_NAME}" = "BINDIR" ]; then | |
| # if [ -n "`echo \"${FNAME}\" | grep '^+'`" ]; then | |
| # FNAME=`echo "${FNAME}" | cut -c2-` | |
| # fi | |
| # fi | |
| # | |
| # First check for anything which contains just dots. | |
| # Also check that '/' has not been set. | |
| # | |
| if [ -n "`echo \"${FNAME}\" | grep -E '(^[./]*$)|[;&]|/\.\./'`" ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Invalid pathname: ${FNAME}" | |
| continue | |
| fi | |
| # | |
| # Next we check to see if it is a relative pathname. However, for | |
| # the SHARED_LIB_WHITELIST option, the pathname may begin with a | |
| # variable ($ORIGIN, ${LIB} etc). We must ignore these entries. | |
| # | |
| if [ -n "`echo \"${FNAME}\" | grep '^[^/].*/'`" ]; then | |
| if [ "${OPT_NAME}" = "SHARED_LIB_WHITELIST" -a -n "`echo \"${FNAME}\" | grep '^\\$'`" ]; then | |
| continue | |
| else | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Relative pathname: ${FNAME}" | |
| fi | |
| elif [ -z "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| # | |
| # Now we check to see if it is a simple file name. | |
| # | |
| # | |
| # Simple file names are allowed for some options. | |
| # | |
| case "${OPT_NAME}" in | |
| USER_FILEPROP_FILES_DIRS|SHARED_LIB_WHITELIST|*_CMD) | |
| continue | |
| ;; | |
| esac | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Simple filename: ${FNAME}" | |
| else | |
| # | |
| # It's an absolute pathname. This could be a file, a directory, | |
| # some other file type, or a non-existent name. | |
| # | |
| # | |
| # This is as far as we go for some options. These pathnames may, | |
| # or may not exist, or may be things other than just files and | |
| # directories. | |
| # | |
| case "${OPT_NAME}" in | |
| PKGMGR_NO_VRFY|EXISTWHITELIST|ALLOWDEVFILE) | |
| continue | |
| ;; | |
| esac | |
| # | |
| # Now test for the different file types. | |
| # | |
| if [ -f "${FNAME}" ]; then | |
| case "${OPT_NAME}" in | |
| ALLOWHIDDENDIR|TMPDIR|DBDIR|BINDIR|SCRIPTDIR|SSH_CONFIG_DIR|SUSPSCAN_DIRS|SUSPSCAN_TEMP|RTKT_DIR_WHITELIST|LOCKDIR) | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Not a directory: ${FNAME}" | |
| ;; | |
| esac | |
| elif [ -d "${FNAME}" ]; then | |
| # | |
| # For the ALLOWHIDDENFILE option we need to allow | |
| # a hidden symbolic link to a directory. | |
| # | |
| test "${OPT_NAME}" = "ALLOWHIDDENFILE" -a -h "${FNAME}" && continue | |
| case "${OPT_NAME}" in | |
| ALLOWHIDDENFILE|RTKT_FILE_WHITELIST|WRITEWHITELIST|IMMUTWHITELIST|SCRIPTWHITELIST|LOGFILE|SYSLOG_CONFIG_FILE|INETD_CONF_PATH|XINETD_CONF_PATH|PASSWORD_FILE|OS_VERSION_FILE|IGNORE_PRELINK_DEP_ERR|MISSING_LOGFILES|EMPTY_LOGFILES|PORT_PATH_WHITELIST|ALLOWIPCPROC|SHARED_LIB_WHITELIST|*_CMD) | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Not a file: ${FNAME}" | |
| ;; | |
| esac | |
| elif [ -h "${FNAME}" ]; then | |
| # | |
| # Generally we will accept broken links since the code will | |
| # simply not be able to use them. However, for some paths | |
| # these are not allowed at all. | |
| # | |
| if [ $NOBROKENLINK -eq 1 ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Broken link found: ${FNAME}" | |
| fi | |
| elif [ -e "${FNAME}" ]; then | |
| # | |
| # This is as far as we go for the hidden files. A hidden | |
| # 'file' can actually be anything other than a directory. | |
| # Similarly, a rootkit 'file' could be something other than | |
| # a regular file. So we allow them. | |
| # | |
| test "${OPT_NAME}" = "ALLOWHIDDENFILE" -o "${OPT_NAME}" = "RTKT_FILE_WHITELIST" && continue | |
| ERRCODE=1 | |
| case "${OPT_NAME}" in | |
| ALLOWHIDDENDIR|RTKT_DIR_WHITELIST|TMPDIR|DBDIR|BINDIR|SCRIPTDIR|SSH_CONFIG_DIR|SUSPSCAN_DIRS|SUSPSCAN_TEMP|LOCKDIR) | |
| RKHTMPVAR2="directory" | |
| ;; | |
| LOGFILE|SYSLOG_CONFIG_FILE|INETD_CONF_PATH|XINETD_CONF_PATH|PASSWORD_FILE|OS_VERSION_FILE|IGNORE_PRELINK_DEP_ERR|MISSING_LOGFILES|EMPTY_LOGFILES|PORT_PATH_WHITELIST|ALLOWIPCPROC|SHARED_LIB_WHITELIST|*_CMD) | |
| RKHTMPVAR2="file" | |
| ;; | |
| *) | |
| RKHTMPVAR2="file or directory" | |
| ;; | |
| esac | |
| echo "Invalid ${OPT_NAME} configuration option: Not a ${RKHTMPVAR2}: ${FNAME}" | |
| else | |
| # | |
| # Some pathnames don't need to exist. | |
| # | |
| test $MUSTEXIST -eq 0 && continue | |
| # | |
| # For the SHARED_LIB_WHITELIST option, we cannot test these | |
| # if they contain a variable in the pathname. | |
| # | |
| if [ "${OPT_NAME}" = "SHARED_LIB_WHITELIST" ]; then | |
| if [ -n "`echo \"${FNAME}\" | grep -E '\\$\\{?(ORIGIN|LIB|PLATFORM)\\}?'`" ]; then | |
| continue | |
| fi | |
| fi | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: Non-existent pathname: `name2text \"${FNAME}\"`" | |
| fi | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| return | |
| } | |
| expand_paths() { | |
| # | |
| # This function will output an expanded list of pathnames. | |
| # | |
| # The first parameter is the variable name containing the | |
| # newline-separated list of pathnames. | |
| # | |
| PATH_LIST=`eval echo \"\\$${1}\"` | |
| test -z "${PATH_LIST}" && return | |
| LIST="" | |
| IFS=$IFSNL | |
| for FNAME in ${PATH_LIST}; do | |
| test -z "${FNAME}" && continue | |
| LIST="${LIST} | |
| ${FNAME}" | |
| done | |
| IFS=$RKHIFS | |
| echo "${LIST}" | sed -e '/^$/d' | |
| return | |
| } | |
| make_space_list() { | |
| # | |
| # This function simply converts its argument into a space-separated list. | |
| # | |
| if [ "${ECHON}" = "c" ]; then | |
| echo $ECHOOPT "${1}\c" | tr '\n' ' ' | tr -s ' ' ' ' | |
| else | |
| echo $ECHON $ECHOOPT "${1}" | tr '\n' ' ' | tr -s ' ' ' ' | |
| fi | |
| return | |
| } | |
| check_is_digit() { | |
| # | |
| # This function checks to see if an option is a valid | |
| # number or not. Typically it must be 0 or 1. | |
| # | |
| # The first parameter is the variable name to check. The | |
| # second parameter is the option name to be used in the error | |
| # messages. An optional third parameter may be given to specify | |
| # that other values are allowed. If this is set to 'ANY', then | |
| # any positive number is allowed. If it is set to 'ANY1', then | |
| # the number must be greater than zero. | |
| # | |
| OPT_VALUE=$1 | |
| OPT_NAME=$2 | |
| OTHERS=$3 | |
| test -z "${OPT_NAME}" && OPT_NAME=${OPT_VALUE} | |
| test -z "${OTHERS}" && OTHERS=0 | |
| RKHTMPVAR=`eval echo "\"\\$${OPT_VALUE}\""` | |
| ERRCODE=0 | |
| test -z "${RKHTMPVAR}" && return | |
| # | |
| # If ANY1 is given, then 0 is not a valid number. | |
| # | |
| if [ "${RKHTMPVAR}" = "0" -a "${OTHERS}" = "ANY1" ]; then | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: not a valid number: ${RKHTMPVAR}" | |
| elif [ "${RKHTMPVAR}" != "0" -a "${RKHTMPVAR}" != "1" ]; then | |
| # | |
| # Some options may allow a slightly different value. | |
| # | |
| if [ -n "${OTHERS}" ]; then | |
| if [ "${OTHERS}" = "ANY" -a -n "`echo \"${RKHTMPVAR}\" | grep '^[0-9][0-9]*$'`" ]; then | |
| return | |
| elif [ "${OTHERS}" = "ANY1" -a -n "`echo \"${RKHTMPVAR}\" | grep '^[1-9][0-9]*$'`" ]; then | |
| return | |
| elif [ "${RKHTMPVAR}" = "${OTHERS}" ]; then | |
| return | |
| fi | |
| fi | |
| ERRCODE=1 | |
| echo "Invalid ${OPT_NAME} configuration option: not a valid number: ${RKHTMPVAR}" | |
| fi | |
| return | |
| } | |
| get_temp_file() { | |
| # | |
| # This function will find a unique pathname which can be | |
| # used as a temporary file. | |
| # | |
| # It takes one parameter which is the pathname for the file, | |
| # excluding the suffix. The function will return the pathname | |
| # in TEMPFILE. The pathname itself is not created. | |
| # | |
| TEMPFILE="" | |
| TEMPFILE_BASE=$1 | |
| if [ -n "${MKTEMP_CMD}" ]; then | |
| TEMPFILE=`${MKTEMP_CMD} "${TEMPFILE_BASE}.XXXXXXXXXX"` | |
| elif [ -n "$RANDOM" ]; then | |
| TEMPFILE="${TEMPFILE_BASE}.$RANDOM" | |
| elif [ $BSDOS -eq 1 ]; then | |
| TEMPFILE="${TEMPFILE_BASE}.`date +%s`" | |
| elif [ -n "`date +%N%s 2>/dev/null | grep '^[0-9][0-9]*$'`" ]; then | |
| TEMPFILE="${TEMPFILE_BASE}.`date +%N%s%N`" | |
| else | |
| TEMPFILE="${TEMPFILE_BASE}.`date +%Y%m%d%H%M%S`" | |
| fi | |
| # | |
| # Remove the file just in case it already exists! | |
| # | |
| rm -f "${TEMPFILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| suckit_extra_checks() { | |
| # | |
| # This function carries out some extra checks of the suckit rootkit. | |
| # There are 3 extra checks, but we only display the result after | |
| # all the checks have completed. As such we store the result of | |
| # each check in a variable, and display the final result based on | |
| # the value of those variables. | |
| # | |
| display --to LOG --type PLAIN --log-indent 2 --nl ROOTKIT_ADD_SUCKIT_LOG | |
| # | |
| # The first check tests the link count of the '/sbin/init' file. | |
| # We use the NLINKS variable to indicate the test result: | |
| # -1 means that no 'stat' command was available | |
| # 0 means that the 'stat' command gave an error | |
| # 1 is okay | |
| # >1 means that suckit may be installed | |
| # | |
| NLINKS=-1 | |
| if [ -n "${STAT_CMD}" ]; then | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then | |
| NLINKS=`${STAT_CMD} --nlink /sbin/init 2>/dev/null` | |
| else | |
| NLINKS=`${STAT_CMD} -c %h /sbin/init 2>/dev/null` | |
| fi | |
| test -z "${NLINKS}" && NLINKS=0 | |
| if [ $NLINKS -eq 0 ]; then | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_LINK_COUNT '/sbin/init' | |
| elif [ $NLINKS -eq 1 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result OK --log-indent 4 ROOTKIT_LINK_COUNT '/sbin/init' | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_LINK_COUNT '/sbin/init' | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 4 ROOTKIT_LINK_COUNT '/sbin/init' | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' stat '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'stat' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'stat' | |
| fi | |
| fi | |
| # | |
| # The next test checks to see if certain files are being | |
| # hidden. These files have the '.xrk' or '.mem' suffix. | |
| # The HIDDEN variable will be used to indicate the result: | |
| # <null> is okay | |
| # 'xrk' means that the 'xrk' suffix is hidden | |
| # 'mem' means that the 'mem' suffix is hidden | |
| # | |
| HIDDEN="" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| for EXT in xrk mem; do | |
| get_temp_file "${RKHTMPDIR}/suckitexttest" | |
| touch "${TEMPFILE}" | |
| rm -f "${TEMPFILE}.${EXT}" >/dev/null 2>&1 | |
| mv "${TEMPFILE}" "${TEMPFILE}.${EXT}" | |
| if [ ! -f "${TEMPFILE}.${EXT}" ]; then | |
| if [ -n "${HIDDEN}" ]; then | |
| HIDDEN="${HIDDEN} and ${EXT}" | |
| else | |
| HIDDEN=${EXT} | |
| fi | |
| fi | |
| rm -f "${TEMPFILE}.${EXT}" >/dev/null 2>&1 | |
| done | |
| if [ -z "${HIDDEN}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_ADD_SUCKIT_EXT | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_ADD_SUCKIT_EXT | |
| fi | |
| # | |
| # Finally we perform a check using the skdet command, if it | |
| # is present. The SKDET variable will be used to indicate | |
| # the result: | |
| # -1 means that skdet is not available | |
| # 0 means that skdet found nothing | |
| # 1 means that skdet found something | |
| # 2 means that the version of skdet is unknown | |
| # | |
| # The variable SKDET_OUTPUT will contain any output from | |
| # the command. | |
| # | |
| SKDET=-1 | |
| SKDET_OUTPUT="" | |
| SKDET_CMD=`find_cmd skdet` | |
| if [ -n "${SKDET_CMD}" ]; then | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FOUND_CMD 'skdet' "${SKDET_CMD}" | |
| fi | |
| # | |
| # We need to check the skdet version first. | |
| # | |
| SKDET=0 | |
| SKDETOPT="" | |
| SKDETVER=`${SKDET_CMD} -v 2>&1 | grep '^skdet.v' | ${AWK_CMD} -F'.' '{ print $1 }'` | |
| case "${SKDETVER}" in | |
| *v0) | |
| SKDETOPT="-a" | |
| ;; | |
| *v1) | |
| SKDETOPT="-c" | |
| ;; | |
| *) | |
| SKDET=2 | |
| SKDET_OUTPUT=`${SKDET_CMD} -v 2>&1` | |
| ;; | |
| esac | |
| if [ $SKDET -eq 0 ]; then | |
| SKDET_OUTPUT=`${SKDET_CMD} ${SKDETOPT} 2>&1 | tr -s ' ' | grep -i 'invis'` | |
| test -n "${SKDET_OUTPUT}" && SKDET=1 | |
| fi | |
| if [ $SKDET -eq 0 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result OK --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET | |
| display --to LOG --type INFO NOT_FOUND_CMD 'skdet' | |
| fi | |
| # | |
| # Now we can display the results. | |
| # | |
| if [ \( $NLINKS -eq 1 -o $NLINKS -eq -1 \) -a -z "${HIDDEN}" -a $SKDET -le 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_ADD_SUCKIT | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}Suckit Rootkit (additional checks), " | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_ADD_SUCKIT | |
| if [ $NLINKS -eq -1 ]; then | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' stat '`" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_DISABLED | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_NOCMD | |
| fi | |
| elif [ $NLINKS -eq 0 ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_LINK_COUNT_CMDERR "${STAT_CMD}" '/sbin/init' | |
| elif [ $NLINKS -gt 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_FOUND "$NLINKS" | |
| fi | |
| if [ -n "${HIDDEN}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_EXT_FOUND "${HIDDEN}" | |
| fi | |
| if [ $SKDET -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_SKDET_FOUND "${SKDET_OUTPUT}" | |
| elif [ $SKDET -eq 2 ]; then | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_SKDET_VER "${SKDET_OUTPUT}" | |
| fi | |
| fi | |
| return | |
| } | |
| scanrootkit() { | |
| # | |
| # This function performs the actual check for a rootkit. | |
| # It uses the variables SCAN_ROOTKIT, SCAN_FILES, SCAN_DIRS | |
| # and SCAN_KSYMS. These will have been set before the | |
| # function is called. | |
| # | |
| SCAN_STATUS=0 | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}" | |
| # | |
| # First check to see if any of the known files exist. | |
| # | |
| FILE_FOUND="" | |
| for RKHTMPVAR2 in ${SCAN_FILES}; do | |
| RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '` | |
| # | |
| # If the option SCANROOTKITMODE is set to "THOROUGH" the scanrootkit() function | |
| # will search (on a per rootkit basis) for filenames in all of the directories (as defined | |
| # by the result of running 'find / -xdev'). While still not optimal, as it | |
| # still searches for only file names as opposed to file contents, this is one step away | |
| # from the rigidity of searching in known (evidence) or default (installation) locations. | |
| # | |
| # THIS OPTION SHOULD NOT BE ENABLED BY DEFAULT. | |
| # | |
| # You should only activate this feature as part of a more thorough investigation which | |
| # should be based on relevant best practices and procedures. | |
| # Apart from ameliorating the case with respect to functionality (e.g. reporting) this feature does not | |
| # concern itself with efficiency so asking for improvements like whitelisting, de-duping or false-positives is | |
| # out of the question. | |
| # | |
| # Enabling this feature implies you have the knowledge to interpret the results properly. | |
| # | |
| case "${SCANROOTKITMODE}" in | |
| THOROUGH) # Search the whole filesystem | |
| test -n "${BASENAME_CMD}" && FNAME=`${BASENAME_CMD} "${RKHTMPVAR}"` || FNAME=`echo "${RKHTMPVAR}" | sed -e 's:^.*/::'` | |
| FILENAMES=`${FIND_CMD} / -xdev -name "${FNAME}"` | |
| if [ -z "${FILENAMES}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_FILE "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| FOUND=0 | |
| IFS=$IFSNL | |
| for FNAME in ${FILENAMES}; do | |
| if [ \( -f "${FNAME}" -a -s "${FNAME}" \) -o -b "${FNAME}" -o -c "${FNAME}" -o -h "${FNAME}" -o -p "${FNAME}" -o -S "${FNAME}" ]; then | |
| FOUND=1 | |
| SCAN_STATUS=1 | |
| FILE_FOUND="${FILE_FOUND} | |
| ${FNAME}" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| test $FOUND -eq 0 && FOUND="NOT_FOUND" || FOUND="FOUND" | |
| display --to LOG --type PLAIN --result ${FOUND} --log-indent 2 ROOTKIT_FILES_DIRS_FILE "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| fi | |
| ;; | |
| *) # Scan the old way | |
| if [ -f "${RKHTMPVAR}" ]; then | |
| # | |
| # We first check to see if the file is whitelisted. Note that we use | |
| # the un-translated file name. This allows us to check for filenames | |
| # with spaces, but without causing problems for our space-delimited test. | |
| # | |
| FNAMEGREP=`echo "${RKHTMPVAR2}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${RKHTMPVAR}\"`" 'known_rkts' | |
| fi | |
| else | |
| SCAN_STATUS=1 | |
| FILE_FOUND="${FILE_FOUND} | |
| ${RKHTMPVAR}" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_FILE "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_FILE "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| ;; | |
| esac | |
| done | |
| # | |
| # Next check to see if any of the directories exist. | |
| # | |
| DIR_FOUND="" | |
| for RKHTMPVAR2 in ${SCAN_DIRS}; do | |
| RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '` | |
| if [ -d "${RKHTMPVAR}" ]; then | |
| # | |
| # We first check to see if the directory is whitelisted. Note that we use | |
| # the un-translated directory name. This allows us to check for directory | |
| # names with spaces, but without causing problems for our space-delimited test. | |
| # | |
| FNAMEGREP=`echo "${RKHTMPVAR2}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL_DIR "`name2text \"${RKHTMPVAR}\"`" 'known_rkts' | |
| fi | |
| else | |
| SCAN_STATUS=1 | |
| DIR_FOUND="${DIR_FOUND} | |
| ${RKHTMPVAR}" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| done | |
| # | |
| # Finally check the kernel symbols file. | |
| # | |
| KSYM_FOUND="" | |
| if [ -n "${SCAN_KSYMS}" ]; then | |
| for KS in ${SCAN_KSYMS}; do | |
| if [ -n "${KSYMS_FILE}" ]; then | |
| FNAMEGREP=`echo "${KS}" | sed -e 's/\./\\\./g'` | |
| if [ -n "`grep ${GREP_OPT} \"${FNAMEGREP}\" \"${KSYMS_FILE}\"`" ]; then | |
| SCAN_STATUS=1 | |
| KSYM_FOUND="${KSYM_FOUND} | |
| ${KS}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}" | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}" | |
| fi | |
| done | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ $SCAN_STATUS -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, " | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| # | |
| # Log any files, directories or kernel symbols found. | |
| # | |
| IFS=$IFSNL | |
| FILE_FOUND=`echo "${FILE_FOUND}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FILE_FOUND}; do | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_FILE_FOUND "`name2text \"${RKHTMPVAR}\"`" | |
| done | |
| DIR_FOUND=`echo "${DIR_FOUND}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${DIR_FOUND}; do | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_DIR_FOUND "`name2text \"${RKHTMPVAR}\"`" | |
| done | |
| KSYM_FOUND=`echo "${KSYM_FOUND}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${KSYM_FOUND}; do | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_KSYM_FOUND "${RKHTMPVAR}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| return | |
| } | |
| check_required_commands() { | |
| # | |
| # This function checks that the required commands are present | |
| # on the system. The function is called twice: initially to check | |
| # that we can at least start running rkhunter; and the second | |
| # time after we have processed BINDIR to ensure that all the | |
| # required commands are present. It takes one parameter used | |
| # to indicate which list of commands to check. | |
| # | |
| LEAVE=0 | |
| if [ $1 -eq 1 ]; then | |
| CMDDIR="${RKHROOTPATH}" | |
| CMDNAMES="${ABSOLUTELY_REQUIRED_CMDS}" | |
| else | |
| CMDDIR="${BINPATHS}" | |
| CMDNAMES="${REQCMDS}" | |
| fi | |
| for CMD in ${CMDNAMES}; do | |
| SEEN=0 | |
| for DIR in ${CMDDIR}; do | |
| if [ -f "${DIR}/${CMD}" -a -x "${DIR}/${CMD}" ]; then | |
| SEEN=1 | |
| break | |
| fi | |
| done | |
| if [ $SEEN -eq 0 ]; then | |
| LEAVE=1 | |
| echo "The command '${CMD}' must be present on the system in order to run rkhunter." | |
| fi | |
| done | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| check_commands() { | |
| # | |
| # We check for some commands used in the tests. If the command | |
| # is found then a variable including the command name is set. | |
| # These commands are not 'required', so nothing happens if the | |
| # command is not found. The commands can be defined in the | |
| # configuration file, and a value of 'DISABLED' will cause a | |
| # command to not exist. A value of 'BUILTIN' may be used for | |
| # the 'stat' and 'readlink' commands, to indicate that the | |
| # supplied scripts should be used. We have to handle the 'stat' | |
| # command in a special way so that the perl module does not get | |
| # used if the command is to be disabled. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| for CMD in ${CMDLIST}; do | |
| CMDNAME=`echo ${CMD} | tr '[:lower:]' '[:upper:]'` | |
| CMDNAME="${CMDNAME}_CMD" | |
| # | |
| # See if the user has defined the command in | |
| # the configuration file. | |
| # | |
| CFG_CMD=`get_option single "${CMDNAME}"` || exit $? | |
| if [ -n "${CFG_CMD}" ]; then | |
| if [ "${CFG_CMD}" = "DISABLED" -o "${CFG_CMD}" = "BUILTIN" ]; then | |
| eval ${CMDNAME}=\"${CFG_CMD}\" | |
| else | |
| MCMD=`echo "${CFG_CMD}" | cut -d' ' -f1` | |
| # | |
| # We must first check that the command name is valid. | |
| # The user may have included globbing characters, or | |
| # used multiple dots, and we do not allow that. | |
| # | |
| check_paths MCMD "${CMDNAME}" "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 1 ]; then | |
| LEAVE=1 | |
| continue | |
| fi | |
| # | |
| # Check that the command is executable. | |
| # | |
| if [ -n "`find_cmd ${MCMD}`" ]; then | |
| eval ${CMDNAME}=\"${CFG_CMD}\" | |
| else | |
| CFG_CMD="" | |
| fi | |
| fi | |
| fi | |
| # | |
| # If the command has not been predefined, or is not | |
| # executable, then go find the command to use. | |
| # | |
| test -z "${CFG_CMD}" && eval ${CMDNAME}=`find_cmd ${CMD}` | |
| done | |
| # | |
| # We can only go this far really if there has been an error. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| return | |
| fi | |
| fi | |
| # | |
| # If we cannot find a 'stat' command, or the supplied script is to | |
| # be used, then we must check to see if perl is available. If it is, | |
| # then the supplied 'stat' script can be used. | |
| # | |
| if [ -n "${PERL_CMD}" -a "${PERL_CMD}" != "DISABLED" ]; then | |
| if [ -z "${STAT_CMD}" -o "${STAT_CMD}" = "BUILTIN" ]; then | |
| if [ -r "${SCRIPT_PATH}/check_modules.pl" ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" File::stat Getopt::Long 2>/dev/null | grep 'NOT installed'` | |
| else | |
| MOD_INSTALLED="module not found" | |
| fi | |
| if [ -z "${MOD_INSTALLED}" -a -r "${SCRIPT_PATH}/stat.pl" ]; then | |
| STAT_CMD="${PERL_CMD} ${SCRIPT_PATH}/stat.pl" | |
| else | |
| STAT_CMD="" | |
| fi | |
| fi | |
| elif [ "${STAT_CMD}" = "BUILTIN" ]; then | |
| STAT_CMD="" | |
| fi | |
| # | |
| # If the readlink command cannot be found, or it does not support | |
| # the '-f' option, then we must use the supplied shell script. | |
| # | |
| if [ "${READLINK_CMD}" != "DISABLED" ]; then | |
| if [ -z "${READLINK_CMD}" -o "${READLINK_CMD}" = "BUILTIN" ]; then | |
| test -x "${SCRIPT_PATH}/readlink.sh" && READLINK_CMD="${SCRIPT_PATH}/readlink.sh" || READLINK_CMD="" | |
| elif [ -n "`${READLINK_CMD} -f \"${SCRIPT_PATH}/readlink.sh\" 2>&1 >/dev/null`" ]; then | |
| test -x "${SCRIPT_PATH}/readlink.sh" && READLINK_CMD="${SCRIPT_PATH}/readlink.sh" || READLINK_CMD="" | |
| fi | |
| fi | |
| # | |
| # For Solaris systems we should use the 'gstrings' command | |
| # rather than 'strings', if it is available. Similarly we | |
| # should use 'gawk' or 'nawk' if it is available rather | |
| # than 'awk'. | |
| # | |
| if [ $SUNOS -eq 1 ]; then | |
| if [ "${STRINGS_CMD}" != "DISABLED" ]; then | |
| RKHTMPVAR=`find_cmd gstrings` | |
| test -n "${RKHTMPVAR}" && STRINGS_CMD="${RKHTMPVAR}" | |
| fi | |
| AWK_CMD=`find_cmd gawk` | |
| if [ -z "${AWK_CMD}" ]; then | |
| AWK_CMD=`find_cmd nawk` | |
| if [ -z "${AWK_CMD}" ]; then | |
| AWK_CMD=`find_cmd /usr/xpg4/bin/awk` | |
| if [ -z "${AWK_CMD}" ]; then | |
| AWK_CMD='awk' | |
| fi | |
| fi | |
| fi | |
| else | |
| AWK_CMD='awk' | |
| fi | |
| # | |
| # For OSX systems we should use the 'gnumfmt' command | |
| # rather than 'numfmt', if it is available. | |
| # | |
| if [ $MACOSX -eq 1 ]; then | |
| if [ "${NUMFMT_CMD}" != "DISABLED" ]; then | |
| RKHTMPVAR=`find_cmd gnumfmt` | |
| test -n "${RKHTMPVAR}" && NUMFMT_CMD="${RKHTMPVAR}" | |
| fi | |
| fi | |
| # | |
| # Now remove all the DISABLED commands. | |
| # | |
| for CMD in ${CMDLIST}; do | |
| RKHTMPVAR=`echo ${CMD} | tr '[:lower:]' '[:upper:]'` | |
| RKHTMPVAR="${RKHTMPVAR}_CMD" | |
| RKHTMPVAR2=`eval echo "\\$${RKHTMPVAR}"` | |
| if [ "${RKHTMPVAR2}" = "DISABLED" -o "${RKHTMPVAR2}" = "BUILTIN" ]; then | |
| eval ${RKHTMPVAR}=\"\" | |
| test "${RKHTMPVAR2}" = "DISABLED" && DISABLED_CMDS="${DISABLED_CMDS} ${CMD}" | |
| fi | |
| done | |
| test -n "${DISABLED_CMDS}" && DISABLED_CMDS=" ${DISABLED_CMDS} " | |
| # | |
| # Finally we can set some variables based on | |
| # whether the commands exist or not. | |
| # | |
| test -n "${NUMFMT_CMD}" && HAVE_NUMFMT=1 | |
| test -n "${READLINK_CMD}" && HAVE_READLINK=1 | |
| return | |
| } | |
| get_installdir_option() { | |
| # | |
| # This function obtains the RKH installation directory. It must | |
| # be set by the installer script, and has no default. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| RKHINSTALLDIR=`get_option single INSTALLDIR` || exit $? | |
| if [ -z "${RKHINSTALLDIR}" ]; then | |
| LEAVE=1 | |
| echo "Invalid INSTALLDIR configuration option - no installation directory specified." | |
| elif [ ! -d "${RKHINSTALLDIR}" ]; then | |
| LEAVE=1 | |
| echo "Installation directory does not exist: ${RKHINSTALLDIR}" | |
| elif [ ! -r "${RKHINSTALLDIR}" ]; then | |
| LEAVE=1 | |
| echo "Installation directory is not readable: ${RKHINSTALLDIR}" | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_language_option() { | |
| # | |
| # First get the option from the command-line or the | |
| # configuration file, and do a simple check on whether | |
| # it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ -n "${LANGUAGE}" ]; then | |
| LANGUAGE=`echo "${LANGUAGE}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${LANGUAGE}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--language' option - no language given." | |
| fi | |
| else | |
| LANGUAGE=`get_option single LANGUAGE` || exit $? | |
| fi | |
| # | |
| # If no language has been set, then use English. | |
| # | |
| test -z "${LANGUAGE}" && LANGUAGE="en" | |
| # | |
| # Now check that the language is available. | |
| # | |
| if [ ! -d "${DB_PATH}/i18n" ]; then | |
| LEAVE=1 | |
| echo "The internationalisation directory does not exist: ${DB_PATH}/i18n" | |
| fi | |
| # | |
| # If we are using the '--update' option, then the language files | |
| # will be installed if they are missing. As such, we cannot check | |
| # them here. | |
| # | |
| if [ $LEAVE -eq 0 ]; then | |
| if [ ! -s "${DB_PATH}/i18n/${LANGUAGE}" -a "${LANGUAGE}" != "en" ]; then | |
| if [ $UPDATE_ONLY -eq 1 ]; then | |
| RKHLANGUPDT=1 | |
| else | |
| LEAVE=1 | |
| echo "The language specified is not available: ${LANGUAGE}" | |
| echo "Use the command 'rkhunter --lang en --list languages' to see the list of available languages." | |
| fi | |
| elif [ ! -s "${DB_PATH}/i18n/en" ]; then | |
| if [ $UPDATE_ONLY -eq 1 ]; then | |
| RKHLANGUPDT=1 | |
| else | |
| LEAVE=1 | |
| echo "The English language file must be present: ${DB_PATH}/i18n/en" | |
| echo "If it has been deleted, then you will need to run 'rkhunter --update' with no other options." | |
| fi | |
| fi | |
| fi | |
| # | |
| # Next sort out the locale used if the language is German. | |
| # | |
| if [ "${LANGUAGE}" = "de" ]; then | |
| ICONV_CMD=`find_cmd iconv` | |
| LOCALE_CMD=`find_cmd locale` | |
| if [ -n "${ICONV_CMD}" -a -n "${LOCALE_CMD}" ]; then | |
| RKHCHRMAP=`${LOCALE_CMD} charmap 2>/dev/null` | |
| test -n "${RKHCHRMAP}" && RKHCHKLOCALE=1 | |
| fi | |
| fi | |
| # | |
| # Finally, find out what languages the user wants to be updated. | |
| # We add in the default language, and 'en', if they have not | |
| # been specified. | |
| # | |
| if [ $UPDATE -eq 1 ]; then | |
| UPDATE_LANG=`get_option space-list UPDATE_LANG` || exit $? | |
| if [ -n "${UPDATE_LANG}" ]; then | |
| UPDATE_LANG=`echo ${UPDATE_LANG}` | |
| if [ -z "`echo \" ${UPDATE_LANG} \" | grep \" ${LANGUAGE} \"`" ]; then | |
| UPDATE_LANG="${UPDATE_LANG} ${LANGUAGE}" | |
| fi | |
| if [ -z "`echo \" ${UPDATE_LANG} \" | grep ' en '`" ]; then | |
| UPDATE_LANG="${UPDATE_LANG} en" | |
| fi | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_logfile_option() { | |
| # | |
| # First get the option from the command-line or the | |
| # configuration file, and do a simple check on whether | |
| # it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ -n "${RKHLOGFILE}" ]; then | |
| RKHLOGFILE=`echo "${RKHLOGFILE}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${RKHLOGFILE}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--logfile' option - no logfile name given." | |
| fi | |
| else | |
| RKHLOGFILE=`get_option single LOGFILE` || exit $? | |
| check_paths RKHLOGFILE LOGFILE "NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ -z "${RKHLOGFILE}" ]; then | |
| RET_CODE=1 | |
| RKHLOGFILE="${DFLT_LOGFILE}" | |
| echo "The default logfile will be used: ${RKHLOGFILE}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| # | |
| # Now check that the given option is usable. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| : | |
| elif [ "${RKHLOGFILE}" = "/dev/null" ]; then | |
| APPEND_LOG=0 | |
| else | |
| LOGDIR=`echo "${RKHLOGFILE}" | sed -e 's:/[^/][^/]*$::'` | |
| if [ -z "`echo \"${LOGDIR}\" | grep '/'`" ]; then | |
| LOGDIR="." | |
| fi | |
| if [ "${LOGDIR}" = "${RKHLOGFILE}" ]; then | |
| LEAVE=1 | |
| echo "No log filename given: ${RKHLOGFILE}" | |
| elif [ ! -e "${LOGDIR}" ]; then | |
| LEAVE=1 | |
| echo "Logfile directory does not exist: ${RKHLOGFILE}" | |
| elif [ ! -d "${LOGDIR}" ]; then | |
| LEAVE=1 | |
| echo "Logfile directory is not a directory: ${RKHLOGFILE}" | |
| elif [ ! -w "${LOGDIR}" ]; then | |
| LEAVE=1 | |
| echo "Logfile directory is not writable: ${RKHLOGFILE}" | |
| elif [ ! -r "${LOGDIR}" ]; then | |
| LEAVE=1 | |
| echo "Logfile directory is not readable: ${RKHLOGFILE}" | |
| elif [ -h "${RKHLOGFILE}" ]; then | |
| LEAVE=1 | |
| echo "Logfile is a symbolic link: ${RKHLOGFILE}" | |
| echo "This is a security problem. The link points to another file, and that file is about to be modified by rkhunter." | |
| elif [ -e "${RKHLOGFILE}" -a ! -f "${RKHLOGFILE}" ]; then | |
| LEAVE=1 | |
| echo "Logfile already exists but it is not a file: ${RKHLOGFILE}" | |
| fi | |
| fi | |
| # | |
| # Now check whether we should append to the logfile | |
| # or overwrite it. We check the configuration file | |
| # option, if it is given, and ensure that it is valid. | |
| # | |
| if [ $APPEND_OPT -eq 0 ]; then | |
| ERRCODE=0 | |
| APPEND_LOG=`get_option single APPEND_LOG` || exit $? | |
| if [ -n "${APPEND_LOG}" ]; then | |
| check_is_digit APPEND_LOG | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| APPEND_LOG=0 | |
| fi | |
| fi | |
| # | |
| # Finally, check if the logfile should be copied if | |
| # there were any errors or warnings. Obviously no | |
| # copy is done if no logfile is used. | |
| # | |
| ERRCODE=0 | |
| RKHTMPVAR=`get_option single COPY_LOG_ON_ERROR` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| check_is_digit RKHTMPVAR COPY_LOG_ON_ERROR | |
| if [ $ERRCODE -eq 0 ]; then | |
| COPY_LOG_ON_ERROR=$RKHTMPVAR | |
| else | |
| LEAVE=1 | |
| fi | |
| else | |
| COPY_LOG_ON_ERROR=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_tmpdir_option() { | |
| # | |
| # First get the option from the command-line or the | |
| # configuration file, and do a simple check on whether | |
| # it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ -n "${RKHTMPDIR}" ]; then | |
| RKHTMPDIR=`echo "${RKHTMPDIR}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${RKHTMPDIR}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--tmpdir' option - no directory name given." | |
| fi | |
| else | |
| RKHTMPDIR=`get_option single TMPDIR` || exit $? | |
| check_paths RKHTMPDIR TMPDIR "NOWILD NOBROKENLINK EXIST" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ -z "${RKHTMPDIR}" ]; then | |
| RET_CODE=1 | |
| RKHTMPDIR="${RKHINSTALLDIR}/lib/rkhunter/tmp" | |
| echo "The default temporary directory will be used: ${RKHTMPDIR}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| # | |
| # Now check that the given option is usable. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| : | |
| elif [ ! -e "${RKHTMPDIR}" ]; then | |
| LEAVE=1 | |
| echo "Temporary directory does not exist: ${RKHTMPDIR}" | |
| elif [ ! -d "${RKHTMPDIR}" ]; then | |
| LEAVE=1 | |
| echo "Temporary directory is not a directory: ${RKHTMPDIR}" | |
| elif [ ! -w "${RKHTMPDIR}" ]; then | |
| LEAVE=1 | |
| echo "Temporary directory is not writable: ${RKHTMPDIR}" | |
| elif [ ! -r "${RKHTMPDIR}" ]; then | |
| LEAVE=1 | |
| echo "Temporary directory is not readable: ${RKHTMPDIR}" | |
| elif [ "${RKHTMPDIR}" = "/tmp" -o "${RKHTMPDIR}" = "/var/tmp" ]; then | |
| LEAVE=1 | |
| echo "Do not use ${RKHTMPDIR} as the temporary directory." | |
| echo "This directory will be used by rkhunter to contain system files, so the directory must be secure." | |
| elif [ "${RKHTMPDIR}" = "/etc" ]; then | |
| LEAVE=1 | |
| echo "Do not use ${RKHTMPDIR} as the temporary directory." | |
| echo "This directory will be used by rkhunter to copy and delete certain system files." | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_dbdir_option() { | |
| # | |
| # First get the option from the command-line or the | |
| # configuration file, and do a simple check on whether | |
| # it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ -n "${DB_PATH}" ]; then | |
| DB_PATH=`echo "${DB_PATH}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${DB_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--dbdir' option - no directory name given." | |
| fi | |
| else | |
| DB_PATH=`get_option single DBDIR` || exit $? | |
| check_paths DB_PATH DBDIR "NOWILD EXIST NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ -z "${DB_PATH}" ]; then | |
| RET_CODE=1 | |
| DB_PATH="${RKHINSTALLDIR}/lib/rkhunter/db" | |
| echo "The default database directory will be used: ${DB_PATH}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| # | |
| # Now check that the given option is usable. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| : | |
| elif [ ! -e "${DB_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Database directory does not exist: ${DB_PATH}" | |
| elif [ ! -d "${DB_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Database directory is not a directory: ${DB_PATH}" | |
| elif [ ! -r "${DB_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Database directory is not readable: ${DB_PATH}" | |
| elif [ $PROP_UPDATE -eq 1 -o $UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| if [ ! -w "${DB_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Database directory is not writable: ${DB_PATH}" | |
| fi | |
| fi | |
| if [ $LEAVE -eq 0 ]; then | |
| RKHDAT_FILE="${DB_PATH}/rkhunter.dat" | |
| RKH_FILEPROP_LIST="${DB_PATH}/rkhunter_prop_list.dat" | |
| else | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| add_extra_dirs() { | |
| # | |
| # This functions takes care of any additional directories | |
| # that may exist on some systems. After the function is called | |
| # the value of EXTRA_DIRS must be added to whatever variable | |
| # is being used. | |
| # | |
| EXTRA_DIRS="" | |
| if [ $SUNOS -eq 1 ]; then | |
| # | |
| # Add in some other directories, and those which | |
| # contain the Solaris 'companion' software. | |
| # | |
| test -d /usr/gnu && EXTRA_DIRS="${EXTRA_DIRS} /usr/gnu/bin /usr/gnu/sbin /usr/gnu/libexec" | |
| test -d /usr/sfw && EXTRA_DIRS="${EXTRA_DIRS} /usr/sfw/bin /usr/sfw/sbin /usr/sfw/libexec" | |
| test -d /opt/sfw && EXTRA_DIRS="${EXTRA_DIRS} /opt/sfw/bin /opt/sfw/sbin /opt/sfw/libexec" | |
| test -d /usr/xpg4/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/xpg4/bin" | |
| test -d /usr/ccs/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/ccs/bin" | |
| test -d /usr/5bin -a ! -h /usr/5bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/5bin" | |
| test -d /usr/ucb && EXTRA_DIRS="${EXTRA_DIRS} /usr/ucb" | |
| # | |
| # OpenSolaris distributions (e.g. BeleniX) may use | |
| # other directories. | |
| # | |
| test -d /usr/foss && EXTRA_DIRS="${EXTRA_DIRS} /usr/foss/bin /usr/foss/sbin /usr/foss/libexec" | |
| elif [ $BSDOS -eq 1 ]; then | |
| test -d /usr/pkg && EXTRA_DIRS="${EXTRA_DIRS} /usr/pkg/bin /usr/pkg/sbin /usr/pkg/libexec" | |
| elif [ $MACOSX -eq 1 ]; then | |
| # | |
| # Cater for Fink (Mac OS X) additional software. | |
| # | |
| test -d /sw && EXTRA_DIRS="${EXTRA_DIRS} /sw/bin /sw/sbin" | |
| elif [ $IRIXOS -eq 1 ]; then | |
| test -d /usr/ucb && EXTRA_DIRS="${EXTRA_DIRS} /usr/ucb" | |
| test -d /usr/freeware && EXTRA_DIRS="${EXTRA_DIRS} /usr/freeware/bin /usr/freeware/sbin" | |
| test -d /usr/xpg4/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/xpg4/bin" | |
| elif [ -f "/etc/GoboLinuxVersion" ]; then | |
| # | |
| # We have no other easy way of detecting GoboLinux. | |
| # It has a peculiar filesystem layout, so we need to | |
| # add in this little bit of support to help it work | |
| # with RKH. | |
| # | |
| test -d "/System/Links/Executables" && EXTRA_DIRS="${EXTRA_DIRS} /System/Links/Executables" | |
| fi | |
| # | |
| # Finally check if there are any optional | |
| # bin and sbin directories present. | |
| # | |
| test -d /opt && EXTRA_DIRS="${EXTRA_DIRS} /opt/bin /opt/sbin" | |
| test -d /usr/opt && EXTRA_DIRS="${EXTRA_DIRS} /usr/opt/bin /usr/opt/sbin" | |
| return | |
| } | |
| get_bindir_option() { | |
| # | |
| # First get the option from the command-line or the | |
| # configuration file, and do a simple check on whether | |
| # it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ $BINDIR_OPT -eq 1 ]; then | |
| BINPATHS=`echo "${BINPATHS}" | tr -d '"' | tr -d "'" | tr -s ' ' ' '` | |
| if [ "${BINPATHS}" = " " ]; then | |
| LEAVE=1 | |
| echo "Invalid '--bindir' option - no directory names given." | |
| fi | |
| else | |
| BINPATHS=`get_option space-list BINDIR` || exit $? | |
| if [ -z "${BINPATHS}" ]; then | |
| BINPATHS="${DFLT_BINPATHS}" | |
| # | |
| # Under some OS's /bin is a link to /usr/bin, so | |
| # there is no need to look in it. | |
| # | |
| if [ $SUNOS -eq 1 -o $IRIXOS -eq 1 -o "${OPERATING_SYSTEM}" = "AIX" ]; then | |
| if [ -h "/bin" ]; then | |
| RKHTMPVAR="" | |
| for DIR in ${BINPATHS}; do | |
| test "${DIR}" != "/bin" && RKHTMPVAR="${RKHTMPVAR} ${DIR}" | |
| done | |
| BINPATHS=`echo ${RKHTMPVAR}` | |
| fi | |
| fi | |
| add_extra_dirs | |
| BINPATHS="${BINPATHS}${EXTRA_DIRS}" | |
| fi | |
| fi | |
| # | |
| # The BINPATHS list is prepended with the root PATH. However, | |
| # any specified BINDIR directories beginning with a '+' will | |
| # be prepended before the root PATH. | |
| # | |
| # Once that has been done, we check that each directory begins | |
| # with a '/'. We remove any non-existent directories, but we do | |
| # not flag this as an error. We also remove any duplicate directories. | |
| # | |
| if [ $LEAVE -eq 0 ]; then | |
| RKHTMPVAR="" | |
| PREPEND_PATHS="" | |
| for DIR in ${BINPATHS}; do | |
| if [ -n "`echo ${DIR} | grep '^+'`" ]; then | |
| DIR=`echo ${DIR} | cut -c2-` | |
| PREPEND_PATHS="${PREPEND_PATHS} ${DIR}" | |
| fi | |
| done | |
| PREPEND_PATHS=`echo ${PREPEND_PATHS}` | |
| for DIR in ${PREPEND_PATHS} ${RKHROOTPATH} ${BINPATHS}; do | |
| if [ -n "`echo ${DIR} | grep '^+'`" ]; then | |
| # These will already be in PREPEND_PATHS. | |
| continue | |
| elif [ -z "`echo ${DIR} | grep '^/'`" ]; then | |
| LEAVE=1 | |
| test $BINDIR_OPT -eq 1 && RKHTMPVAR2="'--bindir'" || RKHTMPVAR2="BINDIR configuration" | |
| echo "Invalid ${RKHTMPVAR2} option: Invalid directory found: ${DIR}" | |
| elif [ -e "${DIR}" ]; then | |
| if [ -d "${DIR}" ]; then | |
| test -h "${DIR}" && BINISLINK=1 | |
| DIR=`echo "${DIR}" | tr -s '/' | sed -e 's:/$::'` | |
| if [ -z "`echo \" ${RKHTMPVAR} \" | grep \" ${DIR} \"`" ]; then | |
| RKHTMPVAR="${RKHTMPVAR} ${DIR}" | |
| fi | |
| else | |
| LEAVE=1 | |
| test $BINDIR_OPT -eq 1 && RKHTMPVAR2="'--bindir'" || RKHTMPVAR2="BINDIR configuration" | |
| echo "Invalid ${RKHTMPVAR2} option: Not a directory: ${DIR}" | |
| fi | |
| fi | |
| done | |
| if [ $LEAVE -eq 0 ]; then | |
| BINPATHS=`echo ${RKHTMPVAR}` | |
| test $BINDIR_OPT -eq 1 && RKHTMPVAR="--bindir" || RKHTMPVAR="BINDIR" | |
| check_paths BINPATHS "${RKHTMPVAR}" "NOWILD" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| # We need to set something for the remaining checks. | |
| BINPATHS="${DFLT_BINPATHS}" | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_scriptdir_option() { | |
| # | |
| # Get the value from the configuration file, and do a simple | |
| # check on whether it is empty or a space. | |
| # | |
| # Note: The installer will set this option. As such there | |
| # is no default. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SCRIPT_PATH=`get_option single SCRIPTDIR` || exit $? | |
| check_paths SCRIPT_PATH SCRIPTDIR "NOWILD EXIST NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ -z "${SCRIPT_PATH}" ]; then | |
| LEAVE=1 | |
| echo "The SCRIPTDIR configuration option has not been set by the installer." | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| # | |
| # Now check that the given option is usable. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| : | |
| elif [ ! -r "${SCRIPT_PATH}" ]; then | |
| LEAVE=1 | |
| echo "Script directory is not readable: ${SCRIPT_PATH}" | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| find_cmd() { | |
| # | |
| # This function performs a search of the BINPATHS directories | |
| # looking for the requested command. The full pathname is | |
| # returned if the command is found. | |
| # | |
| # If a full pathname is provided then we simply check that | |
| # it is executable. | |
| # | |
| CMD=$1 | |
| test -z "${CMD}" && return | |
| if [ -n "`echo ${CMD} | grep '/'`" ]; then | |
| test -f "${CMD}" -a -x "${CMD}" && echo "${CMD}" | |
| else | |
| for CMDDIR in ${BINPATHS}; do | |
| if [ -f "${CMDDIR}/${CMD}" -a -x "${CMDDIR}/${CMD}" ]; then | |
| echo "${CMDDIR}/${CMD}" | |
| return | |
| fi | |
| done | |
| fi | |
| return | |
| } | |
| get_rootdir_option() { | |
| RKHTMPVAR=`get_option single ROOTDIR` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| echo "The ROOTDIR configuration option is now deprecated." | |
| fi | |
| return | |
| } | |
| get_existwl_option() { | |
| # | |
| # This function gets the configuration option used to whitelist | |
| # files and directories from existing on the system. That is, they | |
| # may or may not exist at the time of checking, but either way it | |
| # will not cause an error. | |
| # | |
| # This option must be processed before other options because it will | |
| # be used to whitelist some subsequent configuration option pathnames. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| EXISTWL_OPT=`get_option newline-list EXISTWHITELIST` || exit $? | |
| if [ -n "${EXISTWL_OPT}" ]; then | |
| EXISTWHITELIST=`expand_paths EXISTWL_OPT` | |
| check_paths EXISTWHITELIST EXISTWHITELIST | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_mailonwarn_option() { | |
| # | |
| # Get the option from the configuration file. If it is set, | |
| # then we get the MAIL_CMD option as well. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| MAILONWARNING=`get_option space-list MAIL-ON-WARNING` || exit $? | |
| if [ -n "${MAILONWARNING}" ]; then | |
| MAILONWARNING=`echo ${MAILONWARNING}` | |
| # | |
| # If an email address is configured, then we need | |
| # to check the email command option as well. | |
| # | |
| MAIL_CMD=`get_option single MAIL_CMD` || exit $? | |
| test -z "${MAIL_CMD}" && MAIL_CMD="mail -s \"[rkhunter] Warnings found for \${HOST_NAME}\"" | |
| MCMD=`echo "${MAIL_CMD}" | cut -d' ' -f1` | |
| check_paths MCMD MAIL_CMD "NOWILD EXIST NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Check that the mail command is executable. | |
| # | |
| MC=`find_cmd ${MCMD}` | |
| if [ -n "${MC}" ]; then | |
| # | |
| # We rebuild the command to use the full pathname. | |
| # | |
| MCMD=`echo "${MAIL_CMD}" | cut -d' ' -f2-` | |
| if [ -z "${MCMD}" -o "${MCMD}" = "${MAIL_CMD}" ]; then | |
| MAIL_CMD=$MC | |
| else | |
| MAIL_CMD="${MC} ${MCMD}" | |
| fi | |
| else | |
| LEAVE=1 | |
| echo "Invalid MAIL_CMD configuration option: command is non-existent or not executable: ${MCMD}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_webcmd_option() { | |
| # | |
| # Get the option from the configuration file. If it is set, | |
| # then we set the RKHWEBCMD_OPTS option as well if necessary. | |
| # | |
| # For backwards compatability we will also check for WEBCMD. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| RKHWEBCMD=`get_option single WEB_CMD` || exit $? | |
| if [ -z "${RKHWEBCMD}" ]; then | |
| RKHWEBCMD=`get_option single WEBCMD` || exit $? | |
| fi | |
| if [ -n "${RKHWEBCMD}" ]; then | |
| WCMD=`echo "${RKHWEBCMD}" | cut -d' ' -f1` | |
| check_paths WCMD WEB_CMD "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Check that the command is executable. | |
| # | |
| WC=`find_cmd ${WCMD}` | |
| if [ -n "${WC}" ]; then | |
| # | |
| # We find if there any command options, and set | |
| # the command to use the full pathname. | |
| # | |
| RKHWEBCMD_OPTS=`echo "${RKHWEBCMD}" | cut -d' ' -f2-` | |
| test "${RKHWEBCMD_OPTS}" = "${RKHWEBCMD}" && RKHWEBCMD_OPTS="" | |
| RKHWEBCMD="${WC}" | |
| test -n "${BASENAME_CMD}" && RKHWEBCMD_BASE=`${BASENAME_CMD} "${WC}"` || RKHWEBCMD_BASE=`echo "${WC}" | sed -e 's:^.*/::'` | |
| else | |
| LEAVE=1 | |
| echo "Invalid WEB_CMD configuration option: command is non-existent or not executable: ${WCMD}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_syslog_option() { | |
| # | |
| # First see if we want to use syslog or not from the command-line | |
| # or configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| USE_SYSLOG=`echo "${USE_SYSLOG}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${USE_SYSLOG}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--syslog' option - no facility/priority names given." | |
| fi | |
| else | |
| USE_SYSLOG=`get_option single USE_SYSLOG` || exit $? | |
| fi | |
| # | |
| # If we are to use syslog, then get the facility and priority levels. | |
| # Additionally, test that they are valid. | |
| # | |
| if [ $LEAVE -eq 0 ]; then | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| USE_SYSLOG=`echo "${USE_SYSLOG}" | tr '[:upper:]' '[:lower:]'` | |
| if [ "${USE_SYSLOG}" = "none" ]; then | |
| # The value of 'none' will be processed later on. | |
| : | |
| elif [ -z "`echo \"${USE_SYSLOG}\" | grep '^[a-z][a-z0-7]*\.[a-z][a-z]*$'`" ]; then | |
| LEAVE=1 | |
| echo "Invalid syslog facility/priority value: ${USE_SYSLOG}" | |
| fi | |
| if [ $LEAVE -eq 0 -a "${USE_SYSLOG}" != "none" ]; then | |
| FOUND=0 | |
| SYSLOG_F=`echo "${USE_SYSLOG}" | cut -d. -f1` | |
| SYSLOG_P=`echo "${USE_SYSLOG}" | cut -d. -f2` | |
| for RKHTMPVAR in auth authpriv cron daemon kern user local0 local1 local2 local3 local4 local5 local6 local7; do | |
| if [ "${SYSLOG_F}" = "${RKHTMPVAR}" ]; then | |
| FOUND=1 | |
| break | |
| fi | |
| done | |
| if [ $FOUND -eq 0 ]; then | |
| LEAVE=1 | |
| echo "Invalid syslog facility name: ${SYSLOG_F}" | |
| fi | |
| FOUND=0 | |
| for RKHTMPVAR in debug info notice warning err crit alert emerg; do | |
| if [ "${SYSLOG_P}" = "${RKHTMPVAR}" ]; then | |
| FOUND=1 | |
| break | |
| fi | |
| done | |
| if [ $FOUND -eq 0 ]; then | |
| LEAVE=1 | |
| echo "Invalid syslog priority name: ${SYSLOG_P}" | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_ssh_options() { | |
| # | |
| # We check some SSH options in this function. They can only | |
| # be set in the configuration file. | |
| # | |
| # | |
| # See if the ALLOW_SSH_ROOT_USER option is specified in the | |
| # configuration file. The value should match what has been set | |
| # in the SSH configuration file for the PermitRootLogin option. | |
| # As such it's value is not just zero or one. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOW_SSH_ROOT_USER=`get_option single ALLOW_SSH_ROOT_USER` || exit $? | |
| if [ -n "${ALLOW_SSH_ROOT_USER}" ]; then | |
| ALLOW_SSH_ROOT_USER=`echo "${ALLOW_SSH_ROOT_USER}" | tr '[:upper:]' '[:lower:]'` | |
| else | |
| # | |
| # By default SSH tends to allow root access. However, we | |
| # do not. By setting this option to 'no', the user will | |
| # receive a warning unless they set the options the same. | |
| # | |
| ALLOW_SSH_ROOT_USER="no" | |
| fi | |
| # | |
| # See if the ALLOW_SSH_PROT_V1 option is specified in the | |
| # configuration file. | |
| # | |
| ALLOW_SSH_PROT_V1=`get_option single ALLOW_SSH_PROT_V1` || exit $? | |
| if [ -n "${ALLOW_SSH_PROT_V1}" ]; then | |
| check_is_digit ALLOW_SSH_PROT_V1 ALLOW_SSH_PROT_V1 2 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| ALLOW_SSH_PROT_V1=0 | |
| fi | |
| # | |
| # See if the directory of the SSH configuration file has been set. | |
| # | |
| SSH_CONFIG_DIR=`get_option single SSH_CONFIG_DIR` || exit $? | |
| if [ -n "${SSH_CONFIG_DIR}" ]; then | |
| check_paths SSH_CONFIG_DIR SSH_CONFIG_DIR "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ ! -r "${SSH_CONFIG_DIR}" ]; then | |
| LEAVE=1 | |
| echo "The SSH configuration file directory is not readable: ${SSH_CONFIG_DIR}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_syslog_config_options() { | |
| # | |
| # We check some syslog configuration options in this function. | |
| # They can only be set in the configuration file. | |
| # | |
| # | |
| # See if the ALLOW_SYSLOG_REMOTE_LOGGING option is specified | |
| # in the configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOW_SYSLOG_REMOTE_LOGGING=`get_option single ALLOW_SYSLOG_REMOTE_LOGGING` || exit $? | |
| if [ -n "${ALLOW_SYSLOG_REMOTE_LOGGING}" ]; then | |
| check_is_digit ALLOW_SYSLOG_REMOTE_LOGGING | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| ALLOW_SYSLOG_REMOTE_LOGGING=0 | |
| fi | |
| # | |
| # See if the pathname to the syslog configuration file has been set. | |
| # | |
| SYSLOG_CONFIG_FILE=`get_option space-list SYSLOG_CONFIG_FILE` || exit $? | |
| if [ -n "${SYSLOG_CONFIG_FILE}" ]; then | |
| if [ -n "`echo \"${SYSLOG_CONFIG_FILE}\" | grep -i '^none$'`" ]; then | |
| SYSLOG_CONFIG_FILE="NONE" | |
| else | |
| check_paths SYSLOG_CONFIG_FILE SYSLOG_CONFIG_FILE "EXIST NOWILD NOBROKENLINK" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_auto_x_option() { | |
| # | |
| # For the second colour set we first see if the auto X detect option | |
| # has been set. If it is set, and X is in use, then the second colour | |
| # set is used. If X is not in use, or the auto detect option is not | |
| # set, then we only use the second colour set if the command-line | |
| # option is used or it is configured in the configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ $AUTO_X_OPT -eq 0 ]; then | |
| AUTO_X_DTCT=`get_option single AUTO_X_DETECT` || exit $? | |
| if [ -n "${AUTO_X_DTCT}" ]; then | |
| check_is_digit AUTO_X_DTCT AUTO_X_DETECT | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| AUTO_X_DTCT=0 | |
| fi | |
| fi | |
| if [ $AUTO_X_DTCT -eq 1 -a -n "$DISPLAY" ]; then | |
| CLRSET2=1 | |
| fi | |
| if [ $CLRSET2 -eq 0 ]; then | |
| CLRSET2=`get_option single COLOR_SET2` || exit $? | |
| if [ -n "${CLRSET2}" ]; then | |
| check_is_digit CLRSET2 COLOR_SET2 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| CLRSET2=0 | |
| fi | |
| fi | |
| # | |
| # Finally, we get the option to see if whitelisted | |
| # results are to be shown as white rather than green. | |
| # | |
| WLIST_IS_WHITE=`get_option single WHITELISTED_IS_WHITE` || exit $? | |
| if [ -n "${WLIST_IS_WHITE}" ]; then | |
| check_is_digit WLIST_IS_WHITE WHITELISTED_IS_WHITE | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| WLIST_IS_WHITE=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_locking_options() { | |
| # | |
| # This function gets the configuration options to see if locking | |
| # should be used when RKH is run. The mechanism for locking uses | |
| # a simple timer, and will display some basic messages while RKH | |
| # is trying to get the lock. | |
| # | |
| # All of these options can only be set in the configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| USE_LOCKING=`get_option single USE_LOCKING` || exit $? | |
| if [ -n "${USE_LOCKING}" ]; then | |
| check_is_digit USE_LOCKING | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| USE_LOCKING=0 | |
| fi | |
| # | |
| # Now get the lock directory to use. If this is unset, then | |
| # we need to look for a suitable directory. | |
| # | |
| LOCKDIR=`get_option single LOCKDIR` || exit $? | |
| if [ -n "${LOCKDIR}" ]; then | |
| check_paths LOCKDIR LOCKDIR "NOWILD EXIST NOBROKENLINK" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| PATHNAMES="/run/lock /var/lock /var/run/lock /run /var/run ${RKHTMPDIR}" | |
| for DIR in ${PATHNAMES}; do | |
| # Check for read/write capability before accepting a default directory. | |
| if [ -d "${DIR}" -a -w "${DIR}" -a -r "${DIR}" ]; then | |
| LOCKDIR="${DIR}" | |
| break | |
| fi | |
| done | |
| if [ -z "${LOCKDIR}" ]; then | |
| LEAVE=1 | |
| echo "No suitable directory found for LOCKDIR configuration option." | |
| echo "Locking directories checked: ${PATHNAMES}" | |
| fi | |
| fi | |
| # | |
| # Check that the directory we have is usable. | |
| # | |
| if [ $LEAVE -eq 1 ]; then | |
| : | |
| elif [ ! -w "${LOCKDIR}" ]; then | |
| LEAVE=1 | |
| echo "The LOCKDIR directory is not writable: `name2text \"${LOCKDIR}\"`" | |
| elif [ ! -r "${LOCKDIR}" ]; then | |
| LEAVE=1 | |
| echo "The LOCKDIR directory is not readable: `name2text \"${LOCKDIR}\"`" | |
| fi | |
| # | |
| # Now get the lock timeout value. This must be a positive integer. | |
| # The default value is 300 seconds (5 minutes). | |
| # | |
| LOCK_TIMEOUT=`get_option single LOCK_TIMEOUT` || exit $? | |
| if [ -n "${LOCK_TIMEOUT}" ]; then | |
| check_is_digit LOCK_TIMEOUT LOCK_TIMEOUT ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| LOCK_TIMEOUT=300 | |
| fi | |
| # | |
| # Finally, we get the option to see if any lock messages should | |
| # be shown or not. If the user has used the '--quiet' option, | |
| # then we cannot display the lock messages. Otherwise, these are | |
| # only shown on the screen, and not logged anywhere. The default | |
| # is to show the messages. | |
| # | |
| if [ $QUIET -eq 0 ]; then | |
| SHOW_LOCK_MSGS=`get_option single SHOW_LOCK_MSGS` || exit $? | |
| if [ -n "${SHOW_LOCK_MSGS}" ]; then | |
| check_is_digit SHOW_LOCK_MSGS | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SHOW_LOCK_MSGS=1 | |
| fi | |
| else | |
| SHOW_LOCK_MSGS=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_scanmode_option() { | |
| # | |
| # This function gets the SCANROOTKITMODE configuration option. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SCANROOTKITMODE=`get_option single SCANROOTKITMODE` || exit $? | |
| if [ -n "${SCANROOTKITMODE}" ]; then | |
| SCANROOTKITMODE=`echo "${SCANROOTKITMODE}" | tr '[:lower:]' '[:upper:]'` | |
| if [ "${SCANROOTKITMODE}" != "THOROUGH" ]; then | |
| LEAVE=1 | |
| echo "Invalid SCANROOTKITMODE configuration option: ${SCANROOTKITMODE}" | |
| fi | |
| else | |
| SCANROOTKITMODE="" | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_shell_options() { | |
| # | |
| # This function gets any specific shell configuration options. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| # | |
| # This option will set the shell's globstar option. | |
| # | |
| GLOBSTAR=`get_option single GLOBSTAR` || exit $? | |
| if [ -n "${GLOBSTAR}" ]; then | |
| check_is_digit GLOBSTAR | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| GLOBSTAR=0 | |
| fi | |
| # | |
| # To ensure that any further options which may include wildcarded paths | |
| # are handled correctly, we need to set the 'globstar' option immediately. | |
| # | |
| if [ $GLOBSTAR -eq 1 ]; then | |
| if [ "${MYSHELL}" = "ksh" ]; then | |
| set -o globstar | |
| else | |
| shopt -s globstar | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| sort_test_lists() { | |
| # | |
| # This function is used to sort the list of test names for | |
| # enabled and disabled tests. The first parameter determines | |
| # which list is to be sorted: | |
| # | |
| # 1: enabled tests | |
| # 2: disabled tests | |
| # | |
| RKHTMPVAR=$1 | |
| test $RKHTMPVAR -eq 1 && ENABLE_TESTS=`echo ${ENABLE_TESTS} | tr ' ' '\n' | sort | uniq` | |
| test $RKHTMPVAR -eq 2 && DISABLE_TESTS=`echo ${DISABLE_TESTS} | tr ' ' '\n' | sort | uniq` | |
| ENABLE_TESTS=`echo ${ENABLE_TESTS}` | |
| DISABLE_TESTS=`echo ${DISABLE_TESTS}` | |
| # | |
| # Finally, test to see if the current lists are the same. | |
| # | |
| if [ "${ENABLE_TESTS}" = "${DISABLE_TESTS}" ]; then | |
| test $ENDIS_OPT -eq 0 && RKHTMPVAR=" configured" || RKHTMPVAR="" | |
| echo "The${RKHTMPVAR} enabled and disabled tests are the same." | |
| if [ $ENDIS_OPT -eq 1 -o $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| check_test_options() { | |
| # | |
| # This function is called after we have obtained the enabled and | |
| # disabled test names. It will check that the test names are valid, | |
| # and remove any enabled test names from the disabled list. | |
| # | |
| # | |
| # First we loop through the enabled and disabled test names, and see | |
| # if the special names of 'all' or 'none' are used. If so, then these | |
| # will either override all the other test names in the list, or be an | |
| # error. We also look for any invalid test names. | |
| # | |
| SEEN=0 | |
| LEAVE=0 | |
| RKHTMPVAR=" `echo ${KNOWN_TESTS}` " | |
| for TEST_NAME in ${ENABLE_TESTS}; do | |
| if [ "${TEST_NAME}" = "all" ]; then | |
| SEEN=1 | |
| elif [ "${TEST_NAME}" = "none" ]; then | |
| if [ $ENABLE_OPT -eq 1 ]; then | |
| LEAVE=1 | |
| echo "'none' cannot be used in the enabled test list." | |
| else | |
| LEAVE=1 | |
| echo "'none' cannot be used in the configured enabled test list." | |
| fi | |
| elif [ -z "`echo \"${RKHTMPVAR}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| LEAVE=1 | |
| echo "Unknown enabled test name given: ${TEST_NAME}" | |
| fi | |
| done | |
| test $SEEN -eq 1 && ENABLE_TESTS="all" | |
| # | |
| # For the disabled tests we need to loop through the | |
| # command-line and configuration file test names separately. | |
| # | |
| SEEN=0 | |
| for TEST_NAME in ${CL_DISABLE_TESTS}; do | |
| if [ "${TEST_NAME}" = "none" ]; then | |
| SEEN=1 | |
| elif [ "${TEST_NAME}" = "all" ]; then | |
| LEAVE=1 | |
| echo "'all' cannot be used in the disabled test list." | |
| elif [ -z "`echo \"${RKHTMPVAR}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| LEAVE=1 | |
| echo "Unknown disabled test name given: ${TEST_NAME}" | |
| fi | |
| done | |
| if [ $USECF -eq 1 ]; then | |
| for TEST_NAME in ${CONFIG_DISABLE_TESTS}; do | |
| if [ "${TEST_NAME}" = "none" ]; then | |
| SEEN=1 | |
| elif [ "${TEST_NAME}" = "all" ]; then | |
| LEAVE=1 | |
| echo "'all' cannot be used in the configured disabled test list." | |
| elif [ -z "`echo \"${RKHTMPVAR}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| LEAVE=1 | |
| echo "Unknown disabled test name in the configuration file: ${TEST_NAME}" | |
| fi | |
| done | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| return | |
| fi | |
| fi | |
| test $SEEN -eq 1 && DISABLE_TESTS="none" | |
| # | |
| # If we are to run all the tests, then we use whatever | |
| # disabled tests the user has given us. | |
| # | |
| test "${ENABLE_TESTS}" = "all" && return | |
| # | |
| # Now we can loop through the command-line enabled specific test names, | |
| # and remove them from the disabled list. We need to do this otherwise | |
| # the tests would not run. We don't bother to do this for the configuration | |
| # file enabled tests because we assume the user has already checked this. | |
| # | |
| if [ $ENABLE_OPT -eq 1 -a "${DISABLE_TESTS}" != "none" ]; then | |
| # | |
| # First get a list of just the group test names. | |
| # | |
| GROUP_TEST_NAMES="" | |
| for RKHTMPVAR in ${GROUPED_TESTS}; do | |
| GROUP_TEST_NAMES="${GROUP_TEST_NAMES} `echo "${RKHTMPVAR}" | cut -d: -f1`" | |
| done | |
| GROUP_TEST_NAMES=" `echo ${GROUP_TEST_NAMES}` " | |
| # | |
| # Now loop through the specific test names. | |
| # | |
| DISABLE_TESTS=" ${DISABLE_TESTS} " | |
| for TEST_NAME in ${ENABLE_TESTS}; do | |
| if [ -z "`echo \"${GROUP_TEST_NAMES}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| if [ -n "`echo \"${DISABLE_TESTS}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| DISABLE_TESTS=`echo "${DISABLE_TESTS}" | sed -e "s/ ${TEST_NAME} / /"` | |
| fi | |
| fi | |
| done | |
| DISABLE_TESTS=`echo ${DISABLE_TESTS}` | |
| if [ -z "${DISABLE_TESTS}" ]; then | |
| DISABLE_TESTS="none" | |
| else | |
| sort_test_lists 2 | |
| fi | |
| fi | |
| # | |
| # Next we expand the enabled test group names. This will leave us | |
| # with a list of specific test names, and their associated group test | |
| # names. We also need to check if a given test name is part of a | |
| # group. If it is, then we must add the group name. | |
| # | |
| for TEST_NAME in ${ENABLE_TESTS}; do | |
| for RKHTMPVAR in ${GROUPED_TESTS}; do | |
| GROUP_NAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep ':'`" ]; then | |
| GROUP_TESTS=`echo "${RKHTMPVAR}" | cut -d: -f2-` | |
| else | |
| GROUP_TESTS="" | |
| fi | |
| if [ "${TEST_NAME}" = "${GROUP_NAME}" ]; then | |
| ENABLE_TESTS="${ENABLE_TESTS} `echo \"${GROUP_TESTS}\" | tr ':' ' '`" | |
| break | |
| elif [ -z "${GROUP_TESTS}" ]; then | |
| continue | |
| elif [ -n "`echo \":${GROUP_TESTS}:\" | grep \":${TEST_NAME}:\"`" ]; then | |
| ENABLE_TESTS="${ENABLE_TESTS} ${GROUP_NAME}" | |
| fi | |
| done | |
| done | |
| ENABLE_TESTS=`echo ${ENABLE_TESTS}` | |
| sort_test_lists 1 | |
| # | |
| # Finally, we temporarily expand the disabled test names and temporarily | |
| # remove any matching names from the enabled test list. Although these | |
| # tests would never run, we need to do this in order to see if the user | |
| # has given us an invalid list of tests. | |
| # | |
| if [ "${DISABLE_TESTS}" != "none" ]; then | |
| TEMP_EN_TESTS="${ENABLE_TESTS}" | |
| TEMP_DIS_TESTS="${DISABLE_TESTS}" | |
| for TEST_NAME in ${TEMP_DIS_TESTS}; do | |
| for RKHTMPVAR in ${GROUPED_TESTS}; do | |
| GROUP_NAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep ':'`" ]; then | |
| GROUP_TESTS=`echo "${RKHTMPVAR}" | cut -d: -f2-` | |
| else | |
| GROUP_TESTS="" | |
| fi | |
| if [ "${TEST_NAME}" = "${GROUP_NAME}" ]; then | |
| TEMP_DIS_TESTS="${TEMP_DIS_TESTS} `echo \"${GROUP_TESTS}\" | tr ':' ' '`" | |
| break | |
| elif [ -z "${GROUP_TESTS}" ]; then | |
| continue | |
| elif [ -n "`echo \":${GROUP_TESTS}:\" | grep \":${TEST_NAME}:\"`" ]; then | |
| TEMP_DIS_TESTS="${TEMP_DIS_TESTS} ${GROUP_NAME}" | |
| fi | |
| done | |
| done | |
| TEMP_DIS_TESTS=" `echo ${TEMP_DIS_TESTS}` " | |
| # | |
| # Now loop through the enabled tests and remove any matches. | |
| # | |
| for TEST_NAME in ${TEMP_EN_TESTS}; do | |
| if [ -n "`echo \"${TEMP_DIS_TESTS}\" | grep \" ${TEST_NAME} \"`" ]; then | |
| TEMP_EN_TESTS=`echo " ${TEMP_EN_TESTS} " | sed -e "s/ ${TEST_NAME} / /"` | |
| fi | |
| done | |
| TEMP_EN_TESTS=`echo ${TEMP_EN_TESTS}` | |
| if [ -z "${TEMP_EN_TESTS}" ]; then | |
| LEAVE=0 | |
| if [ $ENABLE_OPT -eq 1 ]; then | |
| LEAVE=1 | |
| echo "Invalid enabled test list - no tests to run." | |
| else | |
| LEAVE=1 | |
| echo "Invalid configured enabled test list - no tests to run." | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| return | |
| } | |
| get_enable_option() { | |
| # | |
| # This function gets the enabled test names from the command-line | |
| # or the configuration file as required. The test names will be | |
| # checked later on. By default all tests are enabled. | |
| # | |
| # | |
| # Get the command-line test names. These override | |
| # the configuration file enabled test names. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ $ENABLE_OPT -eq 1 ]; then | |
| ENABLE_TESTS=`make_space_list "${CL_ENABLE_TESTS}"` | |
| ENABLE_TESTS=`echo ${ENABLE_TESTS}` | |
| if [ -z "${ENABLE_TESTS}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--enable' option - no test names given." | |
| fi | |
| # | |
| # We do a simple test here to see if just one test was enabled. | |
| # If it was then we skip the key press feature since it is most | |
| # likely that the user doesn't want that. The test name cannot be | |
| # 'all'. | |
| # | |
| if [ "${ENABLE_TESTS}" != "all" -a -z "`echo \"${ENABLE_TESTS}\" | grep ' '`" ]; then | |
| SKIP_KEY_PRESS=1 | |
| fi | |
| else | |
| # | |
| # We get the configuration file entries by default. | |
| # | |
| ENABLE_TESTS=`get_option space-list ENABLE_TESTS` || exit $? | |
| if [ -n "${ENABLE_TESTS}" ]; then | |
| ENABLE_TESTS=`make_space_list "${ENABLE_TESTS}"` | |
| ENABLE_TESTS=`echo ${ENABLE_TESTS}` | |
| if [ -n "${ENABLE_TESTS}" ]; then | |
| ENABLE_TESTS=`echo "${ENABLE_TESTS}" | tr '[:upper:]' '[:lower:]'` | |
| else | |
| # The system default. | |
| ENABLE_TESTS="all" | |
| fi | |
| else | |
| # The system default. | |
| ENABLE_TESTS="all" | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_disable_option() { | |
| # | |
| # This function gets the disabled test names from the command-line | |
| # and the configuration file if required. The test names will be | |
| # checked later on. By default no tests are disabled. | |
| # | |
| # Note: disabled tests are always compared against the list | |
| # of enabled tests. Hence, if we used | |
| # 'rkhunter -c --enable system_commands --disable apps' | |
| # then only the system command tests are run. Any other test is | |
| # not run because it is not in the '--enable' list. As such | |
| # the '--disable' option in the example above is not necessary. | |
| # | |
| # | |
| # Get the command-line test names. | |
| # | |
| LEAVE=0 | |
| if [ -n "${CL_DISABLE_TESTS}" ]; then | |
| CL_DISABLE_TESTS=`make_space_list "${CL_DISABLE_TESTS}"` | |
| CL_DISABLE_TESTS=`echo ${CL_DISABLE_TESTS}` | |
| if [ -z "${CL_DISABLE_TESTS}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--disable' option - no test names given." | |
| fi | |
| fi | |
| # | |
| # Get the configuration file test names | |
| # unless specifically requested not to do so. | |
| # | |
| if [ $USECF -eq 1 ]; then | |
| CONFIG_DISABLE_TESTS=`get_option space-list DISABLE_TESTS` || exit $? | |
| if [ -n "${CONFIG_DISABLE_TESTS}" ]; then | |
| CONFIG_DISABLE_TESTS=`make_space_list "${CONFIG_DISABLE_TESTS}"` | |
| CONFIG_DISABLE_TESTS=`echo ${CONFIG_DISABLE_TESTS}` | |
| if [ -n "${CONFIG_DISABLE_TESTS}" ]; then | |
| CONFIG_DISABLE_TESTS=`echo ${CONFIG_DISABLE_TESTS} | tr '[:upper:]' '[:lower:]'` | |
| fi | |
| fi | |
| fi | |
| if [ $LEAVE -eq 0 ]; then | |
| DISABLE_TESTS="${CL_DISABLE_TESTS} ${CONFIG_DISABLE_TESTS}" | |
| DISABLE_TESTS=`echo ${DISABLE_TESTS}` | |
| if [ -z "${DISABLE_TESTS}" ]; then | |
| # The system default. | |
| DISABLE_TESTS="none" | |
| fi | |
| else | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_xinetd_option() { | |
| # | |
| # This function obtains the inetd and xinetd configuration | |
| # file pathnames from the config file. It also get the | |
| # whitelisted services. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| FNAME=`get_option single INETD_CONF_PATH` || exit $? | |
| if [ -n "${FNAME}" ]; then | |
| check_paths FNAME INETD_CONF_PATH "NOWILD EXIST NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| INETD_CONF_PATH="${FNAME}" | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| INETDALLOWEDSVCS=`get_option space-list INETD_ALLOWED_SVC` || exit $? | |
| # | |
| # Now do the same for xinetd. | |
| # | |
| FNAME=`get_option single XINETD_CONF_PATH` || exit $? | |
| if [ -n "${FNAME}" ]; then | |
| check_paths FNAME XINETD_CONF_PATH "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| XINETD_CONF_PATH="${FNAME}" | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| XINETDALLOWEDSVCS=`get_option space-list XINETD_ALLOWED_SVC` || exit $? | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_port_options() { | |
| # | |
| # This function will get the various PORT configuration options, and | |
| # build up PORT_WHITELIST as a newline-separated list. | |
| # | |
| # First get the PORT_WHITELIST option from the configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| PORT_WHITELIST="" | |
| RKHTMPVAR=`get_option space-list PORT_WHITELIST` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| # | |
| # Loop through the list checking that it all looks okay. | |
| # | |
| for RKHTMPVAR2 in ${RKHTMPVAR}; do | |
| if [ -n "`echo \"${RKHTMPVAR2}\" | grep -E -i '^(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| PROTO=`echo ${RKHTMPVAR2} | cut -d: -f1 | tr '[:lower:]' '[:upper:]'` | |
| PORT=`echo ${RKHTMPVAR2} | cut -d: -f2` | |
| if [ $PORT -gt 65535 ]; then | |
| LEAVE=1 | |
| echo "Invalid PORT_WHITELIST configuration option - invalid port specified: `name2text \"${RKHTMPVAR2}\"`" | |
| fi | |
| PORT_WHITELIST="${PORT_WHITELIST} | |
| ${PROTO}:${PORT}" | |
| elif [ "${RKHTMPVAR2}" = "*" ]; then | |
| if [ -n "${LSOF_CMD}" ]; then | |
| PORT_WHITELIST_ALL_TRUSTED=1 | |
| else | |
| LEAVE=1 | |
| echo "Invalid PORT_WHITELIST configuration option - '*' requires the 'lsof' command." | |
| fi | |
| else | |
| LEAVE=1 | |
| echo "Invalid entry specified in PORT_WHITELIST configuration option: `name2text \"${RKHTMPVAR2}\"`" | |
| fi | |
| done | |
| fi | |
| # | |
| # Now get the PORT_PATH_WHITELIST option from the configuration file. | |
| # | |
| RKHTMPVAR=`get_option newline-list PORT_PATH_WHITELIST` || exit $? | |
| if [ -z "${LSOF_CMD}" ]; then | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| LEAVE=1 | |
| echo "Invalid PORT_PATH_WHITELIST configuration option - the 'lsof' command is required." | |
| fi | |
| elif [ -n "${RKHTMPVAR}" ]; then | |
| # | |
| # Loop through the list checking that it all looks okay. | |
| # | |
| IFS=$IFSNL | |
| for RKHTMPVAR2 in ${RKHTMPVAR}; do | |
| if [ -n "`echo \"${RKHTMPVAR2}\" | grep '^/'`" ]; then | |
| PORT=0 | |
| FNAME="" | |
| PROTO="" | |
| # Dig out the protocol and port number, if present. | |
| if [ -n "`echo \"${RKHTMPVAR2}\" | grep -E -i '.:(TCP|UDP):[1-9][0-9]*$'`" ]; then | |
| PROTO=`echo "${RKHTMPVAR2}" | sed -e 's/^.*:\([a-zA-Z]*\):[1-9][0-9]*$/\1/'` | |
| PORT=`echo "${RKHTMPVAR2}" | sed -e 's/^.*:\([1-9][0-9]*\)$/\1/'` | |
| if [ $PORT -gt 65535 ]; then | |
| LEAVE=1 | |
| echo "Invalid PORT_PATH_WHITELIST configuration option - invalid port specified: `name2text \"${RKHTMPVAR2}\"`" | |
| fi | |
| PROTO=`echo ${PROTO} | tr '[:lower:]' '[:upper:]'` | |
| fi | |
| # Dig out the pathname. | |
| if [ $PORT -gt 0 ]; then | |
| FNAME=`echo "${RKHTMPVAR2}" | sed -e 's/^\(.*\):[a-zA-Z]*:[1-9][0-9]*$/\1/'` | |
| else | |
| FNAME="${RKHTMPVAR2}" | |
| fi | |
| IFS=$RKHIFS | |
| check_paths FNAME PORT_PATH_WHITELIST "EXIST NOWILD NOBROKENLINK" | |
| IFS=$IFSNL | |
| if [ $ERRCODE -eq 1 ]; then | |
| LEAVE=1 | |
| else | |
| if [ $PORT -gt 0 ]; then | |
| PORT_WHITELIST="${PORT_WHITELIST} | |
| ${FNAME}:${PROTO}:${PORT}" | |
| else | |
| PORT_WHITELIST="${PORT_WHITELIST} | |
| ${FNAME}" | |
| fi | |
| fi | |
| else | |
| LEAVE=1 | |
| echo "Invalid entry specified in PORT_PATH_WHITELIST configuration option: `name2text \"${RKHTMPVAR2}\"`" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ -n "${PORT_WHITELIST}" ]; then | |
| PORT_WHITELIST=`echo "${PORT_WHITELIST}" | sed -e '/^$/d'` | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_groups_accounts_options() { | |
| # | |
| # Get the location of the password/shadow file. We also cater | |
| # for cases such as BSD systems and users of TCB shadow files. | |
| # If the shadow file itself does not exist, then we look in | |
| # the password file itself to see if it contains the passwords. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SHADOW_FILE=`get_option single PASSWORD_FILE` || exit $? | |
| if [ -n "${SHADOW_FILE}" ]; then | |
| check_paths SHADOW_FILE PASSWORD_FILE "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ -s "${SHADOW_FILE}" ]; then | |
| SHADOW_FILE="${SHADOW_FILE}" | |
| else | |
| SHADOW_FILE="" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| elif [ -s "/etc/shadow" ]; then | |
| SHADOW_FILE="/etc/shadow" | |
| elif [ \( $BSDOS -eq 1 -o $MACOSX -eq 1 \) -a -s "/etc/master.passwd" ]; then | |
| SHADOW_FILE="/etc/master.passwd" | |
| elif [ -f "/etc/tcb/root/shadow" ]; then | |
| HAVE_TCB_SHADOW=1 | |
| elif [ -s "/etc/passwd" ]; then | |
| # | |
| # If the passwords are stored in the passwd file, then | |
| # it should contain at least 3 non-colon characters in the | |
| # second field. Checking for 3 characters allows for normal | |
| # shadow entries such as 'x', '!!' or '*'. It is assumed | |
| # that at least one account will have a password. | |
| # | |
| if [ -n "`grep '^[^:]*:[^:][^:][^:]' /etc/passwd`" ]; then | |
| SHADOW_FILE="/etc/passwd" | |
| fi | |
| fi | |
| # | |
| # Now get the passwordless account whitelist option. | |
| # | |
| PWD_WHITELIST=`get_option space-list PWDLESS_ACCOUNTS` || exit $? | |
| test -n "${PWD_WHITELIST}" && PWD_WHITELIST=" `echo ${PWD_WHITELIST}` " | |
| # | |
| # Next get any root-equivalent whitelisted account names. | |
| # | |
| UID0_WHITELIST=`get_option space-list UID0_ACCOUNTS` || exit $? | |
| # By default we allow the root account. | |
| UID0_WHITELIST=" root `echo ${UID0_WHITELIST}` " | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| test_epoch_cmd() { | |
| # | |
| # This function simply checks if the supplied command | |
| # can process epoch second times. We do this by using | |
| # the '%s' formatting option, and the 'seconds ago' | |
| # time format. If the command understands both of these | |
| # then we can use it for the epoch date. | |
| # | |
| RKHTMPVAR=$1 | |
| if [ -n "`${RKHTMPVAR} --date '5 seconds ago' '+%s' 2>/dev/null | grep '^[0-9][0-9]*$'`" ]; then | |
| EPOCH_DATE_CMD="${RKHTMPVAR}" | |
| fi | |
| return | |
| } | |
| get_epoch_date_cmd_option() { | |
| # | |
| # Get the option from the configuration file, or work out | |
| # if the 'date' command is suitable. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| EPOCH_DATE_CMD=`get_option single EPOCH_DATE_CMD` || exit $? | |
| # | |
| # Check the type of config file option we have. They user may have | |
| # specified a command to use or 'NONE', in which case we return. | |
| # If they specified 'PERL' then check we have a 'perl' command, | |
| # and then return. | |
| # | |
| if [ "${EPOCH_DATE_CMD}" = "PERL" ]; then | |
| EPOCH_DATE_CMD="" | |
| test -z "${PERL_CMD}" && EPOCH_DATE_CMD="NONE" | |
| return | |
| elif [ "${EPOCH_DATE_CMD}" = "NONE" ]; then | |
| return | |
| elif [ -n "${EPOCH_DATE_CMD}" ]; then | |
| RKHTMPVAR=`echo "${EPOCH_DATE_CMD}" | cut -d' ' -f1` | |
| check_paths RKHTMPVAR EPOCH_DATE_CMD "EXIST NOWILD NOBROKENLINK" | |
| # | |
| # Check that the command exists and is executable. | |
| # | |
| if [ $ERRCODE -eq 0 ]; then | |
| FNAME=`find_cmd ${RKHTMPVAR}` | |
| if [ -n "${FNAME}" ]; then | |
| RKHTMPVAR2=`echo "${EPOCH_DATE_CMD}" | cut -d' ' -f2-` | |
| if [ -z "${RKHTMPVAR2}" -o "${RKHTMPVAR2}" = "${EPOCH_DATE_CMD}" ]; then | |
| EPOCH_DATE_CMD="${FNAME}" | |
| else | |
| EPOCH_DATE_CMD="${FNAME} ${RKHTMPVAR2}" | |
| fi | |
| else | |
| EPOCH_DATE_CMD="NONE" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 0 ]; then | |
| # | |
| # Now we test if the 'date' command supports processing epoch seconds. | |
| # | |
| test_epoch_cmd "date" | |
| test -n "${EPOCH_DATE_CMD}" && return | |
| # | |
| # For SunOS systems we need to check some other 'date' commands. | |
| # | |
| if [ $SUNOS -eq 1 ]; then | |
| for RKHTMPVAR2 in `find_cmd gdate` /opt/sfw/bin/date; do | |
| test_epoch_cmd "${RKHTMPVAR2}" | |
| test -n "${EPOCH_DATE_CMD}" && break | |
| done | |
| fi | |
| else | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_phalanx2_option() { | |
| # | |
| # This is a specific function to get the PHALANX2_DIRTEST | |
| # option. It must be a digit, and can only be tested for | |
| # on Linux systems. | |
| # | |
| test $LINUXOS -eq 0 && return | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ROOTKIT_PHALANX2_DIRTESTVAL=`get_option single PHALANX2_DIRTEST` || exit $? | |
| if [ -n "${ROOTKIT_PHALANX2_DIRTESTVAL}" ]; then | |
| check_is_digit ROOTKIT_PHALANX2_DIRTESTVAL | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| ROOTKIT_PHALANX2_DIRTESTVAL=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_dev_options() { | |
| # | |
| # This function processes the ALLOWDEVFILE option which is | |
| # used to whitelist files allowed in the '/dev' directory. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOWDEVFILES="" | |
| ALLOWDEVFILE_OPT=`get_option newline-list ALLOWDEVFILE` || exit $? | |
| if [ -n "${ALLOWDEVFILE_OPT}" ]; then | |
| # Note that we do not get the expanded list of pathnames at | |
| # this point. That will be done when the test actually runs. | |
| ALLOWDEVFILES=${ALLOWDEVFILE_OPT} | |
| check_paths ALLOWDEVFILES ALLOWDEVFILE | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_hidden_options() { | |
| # | |
| # This function processes the ALLOWHIDDENFILE and ALLOWHIDDENDIR | |
| # options which are used to whitelist hidden files and directories. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOWHIDDENFILES="" | |
| ALLOWHIDDENFILE_OPT=`get_option newline-list ALLOWHIDDENFILE` || exit $? | |
| if [ -n "${ALLOWHIDDENFILE_OPT}" ]; then | |
| # Note that we do not get the expanded list of pathnames at | |
| # this point. That will be done when the test actually runs. | |
| ALLOWHIDDENFILES=${ALLOWHIDDENFILE_OPT} | |
| check_paths ALLOWHIDDENFILES ALLOWHIDDENFILE | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| ALLOWHIDDENDIRS="" | |
| ALLOWHIDDENDIR_OPT=`get_option newline-list ALLOWHIDDENDIR` || exit $? | |
| if [ -n "${ALLOWHIDDENDIR_OPT}" ]; then | |
| ALLOWHIDDENDIRS=${ALLOWHIDDENDIR_OPT} | |
| check_paths ALLOWHIDDENDIRS ALLOWHIDDENDIR | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_missing_file_options() { | |
| # | |
| # This function processes the options used to detect missing or | |
| # empty files. Note that we do not use the 'EXIST' option for | |
| # 'check_paths' despite the fact that the files should exist. | |
| # However, if they are missing then that is exactly what we want | |
| # the test to report. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| LOGFILE_MISSING=`get_option space-list MISSING_LOGFILES` || exit $? | |
| if [ -n "${LOGFILE_MISSING}" ]; then | |
| check_paths LOGFILE_MISSING MISSING_LOGFILES "NOWILD" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| LOGFILE_EMPTY=`get_option space-list EMPTY_LOGFILES` || exit $? | |
| if [ -n "${LOGFILE_EMPTY}" ]; then | |
| check_paths LOGFILE_EMPTY EMPTY_LOGFILES "NOWILD" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_unhide_options() { | |
| # | |
| # This function processes the configuration options used | |
| # by the unhide command in the 'hidden_procs' test. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| UNHIDE_TESTS=`get_option space-list UNHIDE_TESTS` || exit $? | |
| if [ -n "${UNHIDE_TESTS}" ]; then | |
| # We need to include a space to avoid the problem with hyphens. | |
| UNHIDE_TESTS=" `echo ${UNHIDE_TESTS}`" | |
| else | |
| UNHIDE_TESTS="sys" | |
| fi | |
| if [ -z "`echo \" ${UNHIDE_TESTS}\" | grep ' [a-zA-Z]'`" ]; then | |
| LEAVE=1 | |
| echo "Invalid UNHIDE_TESTS configuration option - no tests specified: ${UNHIDE_TESTS}" | |
| fi | |
| UNHIDETCP_OPTS="" | |
| RKHTMPVAR=`get_option space-list UNHIDETCP_OPTS` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| for RKHTMPVAR2 in ${RKHTMPVAR}; do | |
| # | |
| # For options we need to add a space to the variable | |
| # to avoid problems with the 'echo' command. | |
| # | |
| if [ -z "`echo \"${RKHTMPVAR2} \" | grep '^-'`" ]; then | |
| # Options must begin with a '-'. | |
| LEAVE=1 | |
| echo "Invalid UNHIDETCP_OPTS configuration option - not a valid option: ${RKHTMPVAR}" | |
| elif [ "${RKHTMPVAR2}" = "-V" -o "${RKHTMPVAR2}" = "-h" ]; then | |
| # Ignore obvious invalid options. | |
| continue | |
| else | |
| UNHIDETCP_OPTS="${UNHIDETCP_OPTS} ${RKHTMPVAR2}" | |
| fi | |
| done | |
| # Add a space to avoid the 'echo' problem with options. | |
| UNHIDETCP_OPTS=`echo "${UNHIDETCP_OPTS} " | sed -e 's/^ *//'` | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_process_options() { | |
| # | |
| # Get any options used by checks on processes. | |
| # | |
| # | |
| # We do no testing of this option because if the user gets it wrong, | |
| # then the processes will show up as warnings. The user should (!) | |
| # then check the configuration file to make sure it is correct. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOWPROCDELFILES=`get_option newline-list ALLOWPROCDELFILE` || exit $? | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_suspscan_options() { | |
| # | |
| # This function processes all the options | |
| # required for the suspscan test. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| # | |
| # Get the directories to scan. | |
| # | |
| SUSPSCAN_DIRS=`get_option space-list SUSPSCAN_DIRS` || exit $? | |
| if [ -z "${SUSPSCAN_DIRS}" ]; then | |
| SUSPSCAN_DIRS="${SUSPSCAN_DFLT_DIRS}" | |
| fi | |
| check_paths SUSPSCAN_DIRS SUSPSCAN_DIRS "EXIST NOBROKENLINK NOWILD" | |
| if [ $ERRCODE -eq 0 ]; then | |
| SUSPSCAN_DIRS=`echo ${SUSPSCAN_DIRS}` | |
| else | |
| LEAVE=1 | |
| fi | |
| # | |
| # Get the tempdir to use. It should be a /dev/shm type. | |
| # | |
| SUSPSCAN_TEMP=`get_option single SUSPSCAN_TEMP` || exit $? | |
| if [ -z "${SUSPSCAN_TEMP}" ]; then | |
| SUSPSCAN_TEMP="${SUSPSCAN_DFLT_TMP}" | |
| fi | |
| check_paths SUSPSCAN_TEMP SUSPSCAN_TEMP "EXIST NOBROKENLINK NOWILD" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ ! -w "${SUSPSCAN_TEMP}" ]; then | |
| LEAVE=1 | |
| echo "The suspscan temporary directory is not writable: ${SUSPSCAN_TEMP}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| # | |
| # Get the maximum file size to handle. | |
| # | |
| SUSPSCAN_MAXSIZE=`get_option single SUSPSCAN_MAXSIZE` || exit $? | |
| if [ -n "${SUSPSCAN_MAXSIZE}" ]; then | |
| check_is_digit SUSPSCAN_MAXSIZE SUSPSCAN_MAXSIZE ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SUSPSCAN_MAXSIZE=$SUSPSCAN_DFLT_MAXSIZE | |
| fi | |
| # | |
| # Get the score threshold, 200 seems sensible. | |
| # | |
| SUSPSCAN_THRESH=`get_option single SUSPSCAN_THRESH` || exit $? | |
| if [ -n "${SUSPSCAN_THRESH}" ]; then | |
| check_is_digit SUSPSCAN_THRESH SUSPSCAN_THRESH ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SUSPSCAN_THRESH=$SUSPSCAN_DFLT_THRESH | |
| fi | |
| # | |
| # Get the line threshold. This exists purely for performance reasons. 3000 seems sensible as | |
| # Linux Kernel Modules don't exceed 2000 lines and for example most binaries in /bin don't exceed 3000 lines. | |
| # Note this configuration option will remain unlisted in both the documentation and configuration file. | |
| # | |
| SUSPSCAN_LINETHRESH=`get_option single SUSPSCAN_LINETHRESH` || exit $? | |
| if [ -n "${SUSPSCAN_LINETHRESH}" ]; then | |
| check_is_digit SUSPSCAN_LINETHRESH SUSPSCAN_LINETHRESH ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SUSPSCAN_LINETHRESH=3000 | |
| fi | |
| # | |
| # Get the debug flag value (defaults to 0). Setting this to 1 will cause verbose messages to be displayed | |
| # which will result in more warnings than you will want. Changing the SUSPSCAN_DEBUG default value implies | |
| # that you know what you are doing and that you don't need help "fixing" things afterwards. | |
| # | |
| SUSPSCAN_DEBUG=`get_option single SUSPSCAN_DEBUG` || exit $? | |
| if [ -n "${SUSPSCAN_DEBUG}" ]; then | |
| check_is_digit SUSPSCAN_DEBUG | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SUSPSCAN_DEBUG=0 | |
| fi | |
| # | |
| # Get any whitelisted file pathnames. | |
| # | |
| SUSPSCAN_WL_OPT=`get_option newline-list SUSPSCAN_WHITELIST` || exit $? | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_ipc_options() { | |
| # | |
| # This function processes the configuration options which | |
| # are used during the shared memory segments checks. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ALLOWIPCPID="" | |
| ALLOWIPCPROC="" | |
| ALLOWIPCUSER="" | |
| # | |
| # First see if any segment PIDs have been whitelisted. | |
| # | |
| ALLOWIPCPID=`get_option space-list ALLOWIPCPID` || exit $? | |
| if [ -n "${ALLOWIPCPID}" ]; then | |
| for RKHTMPVAR in ${ALLOWIPCPID}; do | |
| check_is_digit RKHTMPVAR ALLOWIPCPID ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| done | |
| ALLOWIPCPID=" `echo ${ALLOWIPCPID}` " | |
| fi | |
| # | |
| # Next we check for any whitelisted process names. | |
| # | |
| ALLOWIPCPROC_OPT=`get_option newline-list ALLOWIPCPROC` || exit $? | |
| if [ -n "${ALLOWIPCPROC_OPT}" ]; then | |
| # Note that we do not get the expanded list of pathnames at | |
| # this point. That will be done when the test actually runs. | |
| ALLOWIPCPROC=${ALLOWIPCPROC_OPT} | |
| check_paths ALLOWIPCPROC ALLOWIPCPROC | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| # | |
| # Now check if any usernames have been whitelisted. | |
| # | |
| ALLOWIPCUSER=`get_option space-list ALLOWIPCUSER` || exit $? | |
| if [ -n "${ALLOWIPCUSER}" ]; then | |
| ALLOWIPCUSER=" `echo ${ALLOWIPCUSER}` " | |
| fi | |
| # | |
| # Finally, we check for the configured minimum segment size. | |
| # Any segment above this size is considered to be suspicious. | |
| # | |
| IPC_SEG_SIZE=`get_option single IPC_SEG_SIZE` || exit $? | |
| if [ -n "${IPC_SEG_SIZE}" ]; then | |
| check_is_digit IPC_SEG_SIZE IPC_SEG_SIZE ANY1 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| IPC_SEG_SIZE=$DFLT_SEG_SIZE | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_if_prelinked() { | |
| # | |
| # A prelinked system is defined here as one which has a 'prelink' | |
| # command, and the '/etc/prelink.cache' file exists. | |
| # | |
| if [ -f "/etc/prelink.cache" ]; then | |
| # | |
| # Check that we have a 'prelink' command. If it | |
| # doesn't exist, then we cannot use prelinking. | |
| # | |
| PRELINK_CMD=`find_cmd prelink` | |
| test -z "${PRELINK_CMD}" && return | |
| # | |
| # We test (twice) for the existence of Libsafe since this seems to | |
| # riddle prelink test results with "dependency cycle" errors. | |
| # Don't test for existence of /lib/libsafe since it may be | |
| # installed elsewhere. If Libsafe is found, then we'll skip the | |
| # file properties hash test. | |
| # | |
| LIBSAFE_TEST1="" | |
| LIBSAFE_TEST2="" | |
| if [ -f "/etc/ld.so.preload" ]; then | |
| LIBSAFE_TEST1=`grep 'libsafe' /etc/ld.so.preload 2>&1` | |
| fi | |
| if [ -z "${LIBSAFE_TEST1}" ]; then | |
| LIBSAFE_TEST1=`echo "$LD_PRELOAD" | grep 'libsafe' 2>&1` | |
| fi | |
| if [ -n "${LDD_CMD}" ]; then | |
| if [ -f /lib/libdl.so.? ]; then | |
| LIBSAFE_TEST2=`${LDD_CMD} /lib/libdl.so.? | grep 'libsafe' 2>&1` | |
| fi | |
| if [ -z "${LIBSAFE_TEST2}" -a -f /lib64/libdl.so.? ]; then | |
| LIBSAFE_TEST2=`${LDD_CMD} /lib64/libdl.so.? | grep 'libsafe' 2>&1` | |
| fi | |
| fi | |
| if [ -z "${LIBSAFE_TEST1}" -a -z "${LIBSAFE_TEST2}" ]; then | |
| PRELINKED=1 | |
| # | |
| # Only use 'runcon' if SELinux is enabled. | |
| # | |
| SESTATUS_CMD=`find_cmd sestatus` | |
| if [ -n "${SESTATUS_CMD}" ]; then | |
| if [ -n "`${SESTATUS_CMD} 2>/dev/null | grep ' status: *enabled$'`" ]; then | |
| SELINUX_ENABLED=1 | |
| RUNCON_CMD=`find_cmd runcon` | |
| test -n "${RUNCON_CMD}" && USE_RUNCON=1 | |
| fi | |
| fi | |
| elif [ -n "${LIBSAFE_TEST1}" -a -n "${LIBSAFE_TEST2}" ]; then | |
| SKIP_HASH_MSG=2 | |
| fi | |
| fi | |
| return | |
| } | |
| get_md5_hash_function() { | |
| # | |
| # This is a short function to try and locate | |
| # an MD5 hash function command. | |
| # | |
| if [ $PRELINKED -eq 1 ]; then | |
| if [ $USE_RUNCON -eq 1 ]; then | |
| echo "${RUNCON_CMD} -u root -- ${PRELINK_CMD} --verify --md5" | |
| else | |
| echo "${PRELINK_CMD} --verify --md5" | |
| fi | |
| else | |
| HFUNC=`find_cmd md5sum` | |
| test -z "${HFUNC}" && HFUNC=`find_cmd md5` | |
| if [ -z "${HFUNC}" -a -n "${PERL_CMD}" ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Digest::MD5 2>/dev/null | grep 'Digest::MD5 installed'` | |
| test -n "${MOD_INSTALLED}" && echo "${PERL_CMD} ${SCRIPT_PATH}/filehashsha.pl Digest::MD5 0" | |
| else | |
| echo "${HFUNC}" | |
| fi | |
| fi | |
| return | |
| } | |
| get_sha_hash_function() { | |
| # | |
| # This is a short function to try and locate | |
| # a SHA hash function command. | |
| # | |
| # The function takes one argument which is the | |
| # SHA bit size. | |
| # | |
| SHA_SIZE=$1 | |
| check_is_digit SHA_SIZE HASH_CMD ANY1 | |
| if [ $ERRCODE -eq 1 ]; then | |
| echo "Error: Invalid argument to get_sha_hash_function function: $*" >&2 | |
| return | |
| fi | |
| HFUNC=`find_cmd sha${SHA_SIZE}sum` | |
| if [ -z "${HFUNC}" ]; then | |
| HFUNC=`find_cmd sha${SHA_SIZE}` | |
| if [ -z "${HFUNC}" -a $MACOSX -eq 1 ]; then | |
| HFUNC=`find_cmd shasum` | |
| test -n "${HFUNC}" && HFUNC="${HFUNC} -a $SHA_SIZE" | |
| fi | |
| fi | |
| if [ -z "${HFUNC}" -a -n "${PERL_CMD}" ]; then | |
| MOD_INSTALLED="" | |
| if [ $SHA_SIZE -eq 1 ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Digest::SHA Digest::SHA1 Digest::SHA::PurePerl 2>/dev/null` | |
| elif [ $SHA_SIZE -eq 224 ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Digest::SHA Digest::SHA::PurePerl 2>/dev/null` | |
| else | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Digest::SHA Digest::SHA256 Digest::SHA::PurePerl 2>/dev/null` | |
| fi | |
| USE_MOD=`echo "${MOD_INSTALLED}" | grep -v 'NOT installed' 2>/dev/null | head ${HEAD_OPT}1 | cut -d' ' -f1` | |
| if [ -n "${USE_MOD}" ]; then | |
| HFUNC="${PERL_CMD} "${SCRIPT_PATH}/filehashsha.pl" ${USE_MOD} $SHA_SIZE" | |
| fi | |
| fi | |
| echo "${HFUNC}" | |
| return | |
| } | |
| get_hash_function() { | |
| # | |
| # Get the option from the configuration file, and do a simple | |
| # check on whether it is empty or a space. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ $HASH_OPT -eq 1 ]; then | |
| HASH_FUNC=`echo "${HASH_FUNC}" | tr -d '"' | tr -d "'" | tr -s ' ' ' '` | |
| HASH_CMD=`echo "${HASH_FUNC}" | cut -d' ' -f1` | |
| # Stop globbing from being expanded. | |
| if [ -z "`echo \"${HASH_CMD}\" | grep '[][*?{}]'`" ]; then | |
| HASH_FUNC=`echo ${HASH_FUNC}` | |
| else | |
| LEAVE=1 | |
| HASH_FUNC="NONE" | |
| echo "Invalid '--hash' option: invalid pathname: ${HASH_CMD}" | |
| fi | |
| if [ -z "${HASH_FUNC}" ]; then | |
| LEAVE=1 | |
| HASH_FUNC="NONE" | |
| echo "Invalid '--hash' option: no hash function given." | |
| fi | |
| else | |
| HASH_FUNC=`get_option single HASH_CMD` || exit $? | |
| if [ -z "${HASH_FUNC}" ]; then | |
| HASH_FUNC=`get_option single HASH_FUNC` || exit $? | |
| fi | |
| fi | |
| # | |
| # Test to ensure that globbing and other invalid | |
| # pathnames have not been given. | |
| # | |
| if [ -n "${HASH_FUNC}" ]; then | |
| HASH_CMD=`echo "${HASH_FUNC}" | cut -d' ' -f1` | |
| check_paths HASH_CMD HASH_CMD "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 1 ]; then | |
| LEAVE=1 | |
| HASH_FUNC="NONE" | |
| fi | |
| fi | |
| if [ -n "`echo \"${HASH_FUNC}\" | grep -E -i '^(MD5|SHA1|SHA224|SHA256|SHA384|SHA512|RIPEMD160|WHIRLPOOL|NONE)$'`" ]; then | |
| HASH_FUNC=`echo "${HASH_FUNC}" | tr '[:lower:]' '[:upper:]'` | |
| fi | |
| # | |
| # At this point we have either been given a specific hash function | |
| # command, the reserved word 'NONE', one of the SHA or other functions, | |
| # or nothing. For the SHA and MD5 reserved words we must find the SHA | |
| # or MD5 command, or use the supplied perl scripts. For the RIPEMD160 | |
| # and WHIRLPOOL reserved words, we only use the perl scripts. | |
| # | |
| SHA_SIZE=0 | |
| if [ -z "${HASH_FUNC}" ]; then | |
| test $PRELINKED -eq 1 && HASH_FUNC="SHA1" || HASH_FUNC="SHA256" | |
| fi | |
| case "${HASH_FUNC}" in | |
| SHA1) SHA_SIZE=1 | |
| ;; | |
| SHA224) SHA_SIZE=224 | |
| ;; | |
| SHA256) SHA_SIZE=256 | |
| ;; | |
| SHA384) SHA_SIZE=384 | |
| ;; | |
| SHA512) SHA_SIZE=512 | |
| ;; | |
| esac | |
| if [ $SHA_SIZE -eq 1 -a $PRELINKED -eq 1 ]; then | |
| PRELINK_HASH="SHA1" | |
| if [ $USE_RUNCON -eq 1 ]; then | |
| HASH_FUNC="${RUNCON_CMD} -u root -- ${PRELINK_CMD} --verify --sha" | |
| else | |
| HASH_FUNC="${PRELINK_CMD} --verify --sha" | |
| fi | |
| elif [ $SHA_SIZE -ge 1 ]; then | |
| HASH_FUNC=`get_sha_hash_function $SHA_SIZE` | |
| elif [ "${HASH_FUNC}" = "MD5" ]; then | |
| HF=`get_md5_hash_function` | |
| test -n "${HF}" && HASH_FUNC="${HF}" | |
| if [ $PRELINKED -eq 1 ]; then | |
| PRELINK_HASH="MD5" | |
| elif [ -z "`echo \"${HF}\" | grep '/filehashsha\.pl Digest::MD5'`" ]; then | |
| MD5_CMD="${HF}" | |
| fi | |
| elif [ "${HASH_FUNC}" = "RIPEMD160" ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Crypt::RIPEMD160 2>/dev/null` | |
| if [ -n "`echo \"${MOD_INSTALLED}\" | grep 'Crypt::RIPEMD160 installed'`" ]; then | |
| HASH_FUNC="${PERL_CMD} "${SCRIPT_PATH}/filehashsha.pl" Crypt::RIPEMD160 0" | |
| fi | |
| elif [ "${HASH_FUNC}" = "WHIRLPOOL" ]; then | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Digest::Whirlpool 2>/dev/null` | |
| if [ -n "`echo \"${MOD_INSTALLED}\" | grep 'Digest::Whirlpool installed'`" ]; then | |
| HASH_FUNC="${PERL_CMD} "${SCRIPT_PATH}/filehashsha.pl" Digest::Whirlpool 0" | |
| fi | |
| fi | |
| # | |
| # A final check that the command is actually executable. | |
| # This will ensure that the perl scripts have been installed | |
| # correctly, should they be needed. | |
| # | |
| if [ "${HASH_FUNC}" = "NONE" ]; then | |
| : | |
| elif [ "${HASH_FUNC}" = "MD5" ]; then | |
| LEAVE=1 | |
| if [ $HASH_OPT -eq 1 ]; then | |
| echo "Invalid '--hash' option: no usable hash command or perl module for MD5 could be found." | |
| else | |
| echo "Invalid HASH_CMD configuration option: no usable hash command or perl module for MD5 could be found." | |
| fi | |
| elif [ "${HASH_FUNC}" = "RIPEMD160" -o "${HASH_FUNC}" = "WHIRLPOOL" ]; then | |
| LEAVE=1 | |
| if [ $HASH_OPT -eq 1 ]; then | |
| echo "Invalid '--hash' option: no perl module for ${HASH_FUNC} could be found." | |
| else | |
| echo "Invalid HASH_CMD configuration option: no perl module for ${HASH_FUNC} could be found." | |
| fi | |
| elif [ -n "${HASH_FUNC}" ]; then | |
| HASH_CMD=`echo "${HASH_FUNC}" | cut -d' ' -f1` | |
| HF=`find_cmd ${HASH_CMD}` | |
| if [ -n "${HF}" ]; then | |
| # | |
| # We rebuild the command to use the full pathname. | |
| # | |
| HASH_CMD=`echo "${HASH_FUNC}" | cut -d' ' -f2-` | |
| if [ -z "${HASH_CMD}" -o "${HASH_CMD}" = "${HASH_FUNC}" ]; then | |
| HASH_FUNC=$HF | |
| else | |
| HASH_FUNC="${HF} ${HASH_CMD}" | |
| fi | |
| elif [ $HASH_OPT -eq 1 ]; then | |
| LEAVE=1 | |
| echo "Invalid '--hash' option: command is non-existent or not executable: ${HASH_CMD}" | |
| else | |
| LEAVE=1 | |
| echo "Invalid HASH_CMD configuration option: command is non-existent or not executable: ${HASH_CMD}" | |
| fi | |
| elif [ $HASH_OPT -eq 1 ]; then | |
| LEAVE=1 | |
| echo "Invalid '--hash' option: no usable hash command or perl module could be found." | |
| elif [ $SHA_SIZE -ge 1 ]; then | |
| LEAVE=1 | |
| echo "Invalid HASH_CMD configuration option: no usable hash command or perl module for SHA${SHA_SIZE} could be found." | |
| else | |
| LEAVE=1 | |
| echo "Invalid HASH_CMD configuration option: no usable hash command or perl module could be found." | |
| fi | |
| # | |
| # Now we get the hash field index. We will assume a field value | |
| # of one, but this value must be configurable since we allow | |
| # the user to specify the hash function to use. | |
| # | |
| RKHTMPVAR=`get_option single HASH_FLD_IDX` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| check_is_digit RKHTMPVAR HASH_FLD_IDX ANY1 | |
| if [ $ERRCODE -eq 0 ]; then | |
| HASH_FLD_IDX=${RKHTMPVAR} | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| # | |
| # Next we get the package manager to use for the file | |
| # properties hash check and update. If a file is not owned | |
| # as part of a package, the hash function defined above | |
| # will be used instead. | |
| # | |
| if [ -n "${PKGMGR}" ]; then | |
| PKGMGR=`echo "${PKGMGR}" | tr -d '" ' | tr -d "'"` | |
| if [ -z "${PKGMGR}" ]; then | |
| LEAVE=1 | |
| echo "Invalid '--pkgmgr' option: no package manager given." | |
| fi | |
| else | |
| PKGMGR=`get_option single PKGMGR` || exit $? | |
| fi | |
| PKGMGR=`echo "${PKGMGR}" | tr '[:lower:]' '[:upper:]'` | |
| test "${PKGMGR}" = "NONE" && PKGMGR="" | |
| # | |
| # Now check that the package manager we have been given is valid. | |
| # | |
| case "${PKGMGR}" in | |
| "") | |
| ;; | |
| RPM) | |
| RPM_CMD=`find_cmd rpm` | |
| if [ -z "${RPM_CMD}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the 'rpm' command for package manager 'RPM'." | |
| fi | |
| ;; | |
| DPKG) | |
| DPKG_CMD=`find_cmd dpkg-query` | |
| test -z "${DPKG_CMD}" && DPKG_CMD=`find_cmd dpkg` | |
| if [ -z "${DPKG_CMD}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find 'dpkg-query' or 'dpkg' commands for package manager 'DPKG'." | |
| elif [ ! -d "/var/lib/dpkg/info" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the package database directory (/var/lib/dpkg/info) for package manager 'DPKG'." | |
| fi | |
| if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| PKGMGR_MD5_HASH=`get_md5_hash_function` | |
| if [ -z "${PKGMGR_MD5_HASH}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find an MD5 hash function command to assist package manager 'DPKG'." | |
| fi | |
| fi | |
| ;; | |
| BSD) | |
| PKG_CMD=`find_cmd pkg_info` | |
| if [ -z "${PKG_CMD}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the 'pkg_info' command for package manager 'BSD'." | |
| elif [ ! -d "/var/db/pkg" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the package database directory (/var/db/pkg) for package manager 'BSD'." | |
| fi | |
| if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| PKGMGR_MD5_HASH=`get_md5_hash_function` | |
| if [ -z "${PKGMGR_MD5_HASH}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find an MD5 hash function command to assist package manager 'BSD'." | |
| fi | |
| fi | |
| ;; | |
| BSDNG) | |
| PKG_CMD=`find_cmd pkg` | |
| if [ -z "${PKG_CMD}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the 'pkg' command for package manager 'BSDng'." | |
| else | |
| ${PKG_CMD} -N >/dev/null 2>&1 | |
| ERRCODE=$? | |
| if [ $ERRCODE -ne 0 ]; then | |
| LEAVE=1 | |
| echo "System not set up for use with package manager 'BSDng'." | |
| fi | |
| fi | |
| if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| PKGMGR_SHA_HASH=`get_sha_hash_function 256` | |
| if [ -z "${PKGMGR_SHA_HASH}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find a SHA256 hash function command to assist package manager 'BSDng'." | |
| fi | |
| fi | |
| ;; | |
| SOLARIS) | |
| # | |
| # For the Solaris package manager, see if we want | |
| # to use the stored 16-bit checksum or not. | |
| # | |
| USE_SUNSUM=`get_option single USE_SUNSUM` || exit $? | |
| if [ -n "${USE_SUNSUM}" ]; then | |
| check_is_digit USE_SUNSUM | |
| if [ $ERRCODE -eq 0 ]; then | |
| SUM_CMD=`find_cmd sum` | |
| if [ -z "${SUM_CMD}" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the 'sum' command for package manager 'SOLARIS'." | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| else | |
| USE_SUNSUM=0 | |
| fi | |
| if [ ! -f "/var/sadm/install/contents" ]; then | |
| LEAVE=1 | |
| echo "Unable to find the package database file (/var/sadm/install/contents) for package manager 'SOLARIS'." | |
| fi | |
| ;; | |
| *) | |
| LEAVE=1 | |
| echo "Invalid package manager given: ${PKGMGR}" | |
| ;; | |
| esac | |
| # | |
| # Finally we see if any files are to be exempt from the | |
| # package manager verification. These will go through the | |
| # usual commands to get the file info, so they will still | |
| # be tested. | |
| # | |
| PKGMGRNOVRFY=`get_option newline-list PKGMGR_NO_VRFY` || exit $? | |
| if [ -n "${PKGMGRNOVRFY}" ]; then | |
| check_paths PKGMGRNOVRFY PKGMGR_NO_VRFY "EXIST NOWILD NOBROKENLINK" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_scan_mode_dev_option() { | |
| # | |
| # SCAN_MODE_DEV governs how we scan '/dev' for suspicious files. | |
| # The two allowed values are "THOROUGH" or "LAZY". If the option | |
| # is commented out, the default, then we do a THOROUGH scan, which | |
| # will increase the runtime of rkhunter. | |
| # | |
| # | |
| # See if the option is specified in the configuration file. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SCAN_MODE_DEV=`get_option single SCAN_MODE_DEV` || exit $? | |
| if [ -n "${SCAN_MODE_DEV}" ]; then | |
| SCAN_MODE_DEV=`echo "${SCAN_MODE_DEV}" | tr '[:lower:]' '[:upper:]'` | |
| case "${SCAN_MODE_DEV}" in | |
| THOROUGH|LAZY) | |
| ;; | |
| *) # Don't make this fatal. | |
| echo "Invalid SCAN_MODE_DEV configuration option: ${SCAN_MODE_DEV}" | |
| echo "Defaulting to THOROUGH mode." | |
| SCAN_MODE_DEV="THOROUGH" | |
| ;; | |
| esac | |
| else | |
| SCAN_MODE_DEV="THOROUGH" | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_startup_paths_option() { | |
| # | |
| # This function gets the system startup files and directories | |
| # from the configuration file. There are no defaults. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| STARTUP_PATHS=`get_option space-list STARTUP_PATHS` || exit $? | |
| if [ -n "${STARTUP_PATHS}" ]; then | |
| # | |
| # First see if we have any startup files or not. | |
| # | |
| if [ -n "`echo \"${STARTUP_PATHS}\" | grep -i '^none$'`" ]; then | |
| STARTUP_PATHS="NONE" | |
| else | |
| # | |
| # Check that the given files and directories are usable. | |
| # | |
| check_paths STARTUP_PATHS STARTUP_PATHS "EXIST" | |
| if [ $ERRCODE -eq 0 ]; then | |
| for FNAME in ${STARTUP_PATHS}; do | |
| test -f "${FNAME}" && RKHTMPVAR="file" || RKHTMPVAR="directory" | |
| if [ -h "${FNAME}" ]; then | |
| LEAVE=1 | |
| echo "Invalid STARTUP_PATHS configuration option: the ${RKHTMPVAR} is a link: ${FNAME}" | |
| elif [ ! -r "${FNAME}" ]; then | |
| LEAVE=1 | |
| echo "Invalid STARTUP_PATHS configuration option: the ${RKHTMPVAR} is not readable: ${FNAME}" | |
| elif [ ! -s "${FNAME}" ]; then | |
| LEAVE=1 | |
| echo "Invalid STARTUP_PATHS configuration option: the ${RKHTMPVAR} is empty: ${FNAME}" | |
| fi | |
| done | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_rtkt_whitelist_options() { | |
| # | |
| # This function gets any whitelisted rootkit files | |
| # and directories from the configuration file. | |
| # There are no defaults. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| RTKT_FILE_WHITELIST=`get_option newline-list RTKT_FILE_WHITELIST` || exit $? | |
| if [ -n "${RTKT_FILE_WHITELIST}" ]; then | |
| # | |
| # Check that the given files are usable. But we must | |
| # first strip off any trailing text from the end if | |
| # it is present. | |
| # | |
| IFS=$IFSNL | |
| RKHTMPVAR="" | |
| for RKHTMPVAR2 in ${RTKT_FILE_WHITELIST}; do | |
| FNAME=`echo "${RKHTMPVAR2}" | sed -e 's/^\(.*\):[^:]*$/\1/'` | |
| RKHTMPVAR="${RKHTMPVAR} | |
| ${FNAME}" | |
| done | |
| IFS=$RKHIFS | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e '/^$/d'` | |
| check_paths RKHTMPVAR RTKT_FILE_WHITELIST "EXIST NOWILD NOBROKENLINK" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| RTKT_DIR_WHITELIST=`get_option newline-list RTKT_DIR_WHITELIST` || exit $? | |
| if [ -n "${RTKT_DIR_WHITELIST}" ]; then | |
| # | |
| # Check that the given directories are usable. | |
| # | |
| check_paths RTKT_DIR_WHITELIST RTKT_DIR_WHITELIST "EXIST NOWILD NOBROKENLINK" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_shared_lib_whitelist_option() { | |
| # | |
| # This function gets any whitelisted shared library files | |
| # from the configuration file. There are no defaults. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SHARED_LIB_WHITELIST=`get_option space-list SHARED_LIB_WHITELIST` || exit $? | |
| if [ -n "${SHARED_LIB_WHITELIST}" ]; then | |
| check_paths SHARED_LIB_WHITELIST SHARED_LIB_WHITELIST "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| SHARED_LIB_WHITELIST=" `echo ${SHARED_LIB_WHITELIST}` " | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_mirror_options() { | |
| # | |
| # This function gets the mirrors file options. | |
| # | |
| # | |
| # First we see if the mirrors.dat file | |
| # should be rotated when it is used. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ROTATE_MIRRORS=`get_option single ROTATE_MIRRORS` || exit $? | |
| if [ -n "${ROTATE_MIRRORS}" ]; then | |
| check_is_digit ROTATE_MIRRORS | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| ROTATE_MIRRORS=1 | |
| fi | |
| # | |
| # Now check that the mirrors file is usable. | |
| # | |
| if [ -e "${DB_PATH}/mirrors.dat" -a \( ! -f "${DB_PATH}/mirrors.dat" -o -h "${DB_PATH}/mirrors.dat" \) ]; then | |
| LEAVE=1 | |
| echo "The mirrors file is not a file: ${DB_PATH}/mirrors.dat" | |
| fi | |
| if [ $LEAVE -eq 0 -a $VERSIONCHECK -eq 1 ]; then | |
| if [ $ROTATE_MIRRORS -eq 0 ]; then | |
| # The mirrors file only needs to be readable. | |
| if [ ! -e "${DB_PATH}/mirrors.dat" -o ! -s "${DB_PATH}/mirrors.dat" ]; then | |
| LEAVE=1 | |
| echo "The mirrors file does not exist or is empty: ${DB_PATH}/mirrors.dat" | |
| echo "Run 'rkhunter --update'" to restore the default mirrors file. | |
| echo "The default mirror will be used." | |
| fi | |
| else | |
| # The mirrors file needs to be writable. | |
| if [ ! -e "${DB_PATH}/mirrors.dat" -o ! -s "${DB_PATH}/mirrors.dat" ]; then | |
| LEAVE=1 | |
| echo "The mirrors file does not exist or is empty: ${DB_PATH}/mirrors.dat" | |
| echo "Run 'rkhunter --update'" to restore the default mirrors file. | |
| elif [ ! -w "${DB_PATH}/mirrors.dat" ]; then | |
| LEAVE=1 | |
| echo "The mirrors file is not writable: ${DB_PATH}/mirrors.dat" | |
| fi | |
| fi | |
| fi | |
| # | |
| # Next we see if the mirrors file is to be updated when | |
| # we use the '--update' option. | |
| # | |
| if [ $UPDATE -eq 1 ]; then | |
| UPDATE_MIRRORS=`get_option single UPDATE_MIRRORS` || exit $? | |
| if [ -n "${UPDATE_MIRRORS}" ]; then | |
| check_is_digit UPDATE_MIRRORS | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| UPDATE_MIRRORS=1 | |
| fi | |
| fi | |
| # | |
| # Finally, we see which mirrors are to be used. | |
| # | |
| MIRRORS_MODE=`get_option single MIRRORS_MODE` || exit $? | |
| if [ -n "${MIRRORS_MODE}" ]; then | |
| check_is_digit MIRRORS_MODE MIRRORS_MODE 2 | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| MIRRORS_MODE=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_os_info_options() { | |
| # | |
| # This function gets configuration options relating | |
| # to obtaining information about the O/S. | |
| # | |
| # The first part gets the 'release' file pathname | |
| # from the configuration file. There is no default. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| OS_VERSION_FILE=`get_option single OS_VERSION_FILE` || exit $? | |
| if [ -n "${OS_VERSION_FILE}" ]; then | |
| # | |
| # We must have a real pathname for this option. So, if it is a link, | |
| # then we get its real pathname before any further tests. | |
| # | |
| if [ $HAVE_READLINK -eq 1 -a -h "${OS_VERSION_FILE}" ]; then | |
| OS_VERSION_FILE=`${READLINK_CMD} ${READLINK_OPT} "${OS_VERSION_FILE}"` | |
| fi | |
| # | |
| # Check that the given file is usable. | |
| # | |
| check_paths OS_VERSION_FILE OS_VERSION_FILE "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ ! -r "${OS_VERSION_FILE}" ]; then | |
| LEAVE=1 | |
| echo "Invalid OS_VERSION_FILE configuration option: File is not readable: ${OS_VERSION_FILE}" | |
| elif [ ! -s "${OS_VERSION_FILE}" ]; then | |
| LEAVE=1 | |
| echo "Invalid OS_VERSION_FILE configuration option: File is empty: ${OS_VERSION_FILE}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| # | |
| # Next we get the option as to whether we should | |
| # issue a warning when the O/S info changes or not. | |
| # | |
| WARN_ON_OS_CHANGE=`get_option single WARN_ON_OS_CHANGE` || exit $? | |
| if [ -n "${WARN_ON_OS_CHANGE}" ]; then | |
| check_is_digit WARN_ON_OS_CHANGE | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| WARN_ON_OS_CHANGE=1 | |
| fi | |
| # | |
| # Now get the option as to whether we should automatically run | |
| # a properties update ('--propupd') if the O/S has changed. | |
| # | |
| UPDT_ON_OS_CHANGE=`get_option single UPDT_ON_OS_CHANGE` || exit $? | |
| if [ -n "${UPDT_ON_OS_CHANGE}" ]; then | |
| check_is_digit UPDT_ON_OS_CHANGE | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| UPDT_ON_OS_CHANGE=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_user_fileprop_list() { | |
| # | |
| # This function gets any user supplied files and directories | |
| # for the file properties check and the properties file update. | |
| # It stores the different types of files and directories | |
| # found in different variables. Only basic syntax checking is | |
| # done here, further checking will be done later on. | |
| # | |
| # The configuration options can have three basic values: | |
| # | |
| # 1) A simple file (command) name - for example, 'top' | |
| # 2) A directory - for example, '/usr/local/sbin' | |
| # 3) A full file pathname - for example, '/usr/local/sbin/backup' | |
| # | |
| # The first two are simply added to the internal lists of files | |
| # and directories. These are then used to build the file properties | |
| # file list. The third type is added directly to the end of the file. | |
| # | |
| # The second and third types may be wildcarded. They may also be | |
| # excluded from the checks by including them in the | |
| # EXCLUDE_USER_FILEPROP_FILES_DIRS option. Only files and directories | |
| # matching user added ones can be excluded. This prevents users from | |
| # excluding anything in the internal list. | |
| # For example: USER_FILEPROP_FILES_DIRS=/opt/b* | |
| # EXCLUDE_USER_FILEPROP_FILES_DIRS=/opt/backup | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| for WHICH_OPT in USER_FILEPROP_FILES_DIRS EXCLUDE_USER_FILEPROP_FILES_DIRS; do | |
| FILENAMES=`get_option newline-list ${WHICH_OPT}` || exit $? | |
| test -z "${FILENAMES}" && continue | |
| # | |
| # We must first check to see if any of the names are | |
| # simple names but with wildcard characters included. | |
| # | |
| RKHTMPVAR=`echo "${FILENAMES}" | grep '^[^/]*[][?*{}]'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| LEAVE=1 | |
| # Make a space-separated list but without expanding the wildcards. | |
| RKHTMPVAR=`make_space_list "${RKHTMPVAR}"` | |
| echo "Invalid ${WHICH_OPT} configuration option: Invalid pathname(s): ${RKHTMPVAR}" | |
| fi | |
| # | |
| # Next check the pathnames to ensure they are basically valid. | |
| # | |
| check_paths FILENAMES ${WHICH_OPT} "EXIST" | |
| if [ $ERRCODE -eq 1 ]; then | |
| LEAVE=1 | |
| continue | |
| fi | |
| # | |
| # Now expand any wildcards. | |
| # | |
| FNAMES=`expand_paths FILENAMES` | |
| # | |
| # Now we loop through the entries and check them again. They | |
| # are then added to the relevant variable used to build the | |
| # file properties file list. | |
| # | |
| IFS=$IFSNL | |
| for FNAME in ${FNAMES}; do | |
| # | |
| # First check for any files or directories to be excluded. | |
| # We ignore any real checks on the pathnames since it is | |
| # safer if they fail (the relevant files/directories will | |
| # then be included in the file properties checks). | |
| # | |
| if [ "${WHICH_OPT}" = "EXCLUDE_USER_FILEPROP_FILES_DIRS" ]; then | |
| test -z "${USER_EXCLUDE_PROP}" && USER_EXCLUDE_PROP="${FNAME}" || USER_EXCLUDE_PROP="${USER_EXCLUDE_PROP} | |
| ${FNAME}" | |
| continue | |
| fi | |
| # | |
| # Now check to see if it is a simple file name. | |
| # | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| # Check that the file name hasn't already been set. If it has, then we just ignore it. | |
| if [ -z "`echo \"${USER_SIMPLE_FILE_LIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| test -z "${USER_SIMPLE_FILE_LIST}" && USER_SIMPLE_FILE_LIST="${FNAME}" || USER_SIMPLE_FILE_LIST="${USER_SIMPLE_FILE_LIST} | |
| ${FNAME}" | |
| fi | |
| else | |
| # It's an absolute pathname. This could be a file or a directory. | |
| if [ -f "${FNAME}" -o -h "${FNAME}" ]; then | |
| # Check that it hasn't already been set. If it has, then we just ignore it. | |
| test -n "`echo \"${USER_FILE_LIST}\" | grep \"^${FNAMEGREP}$\"`" && continue | |
| if [ -h "${FNAME}" -a $HAVE_READLINK -eq 1 ]; then | |
| RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| FNAMEGREP=`echo "${RKHTMPVAR}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${USER_FILE_LIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| FNAME="${FNAME} | |
| ${RKHTMPVAR}" | |
| fi | |
| elif [ -z "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| LEAVE=1 | |
| echo "Invalid ${WHICH_OPT} configuration option: Broken link found: ${FNAME}" | |
| continue | |
| fi | |
| fi | |
| # | |
| # Now add the file name. | |
| # | |
| test -z "${USER_FILE_LIST}" && USER_FILE_LIST="${FNAME}" || USER_FILE_LIST="${USER_FILE_LIST} | |
| ${FNAME}" | |
| elif [ -d "${FNAME}" ]; then | |
| if [ -h "${FNAME}" -a $HAVE_READLINK -eq 1 ]; then | |
| RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| if [ -z "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| LEAVE=1 | |
| echo "Invalid ${WHICH_OPT} configuration option: Broken link found: `name2text \"${FNAME}\"`" | |
| continue | |
| fi | |
| elif [ "${RKHTMPVAR}" = "/" ]; then | |
| LEAVE=1 | |
| echo "Invalid ${WHICH_OPT} configuration option: Invalid pathname: `name2text \"${FNAME}\"` -> /" | |
| continue | |
| fi | |
| FNAME="${RKHTMPVAR}" | |
| fi | |
| # | |
| # Check that the name hasn't already been set. If it has, then we just ignore it. | |
| # | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${USER_DIR_LIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| test -z "${USER_DIR_LIST}" && USER_DIR_LIST="${FNAME}" || USER_DIR_LIST="${USER_DIR_LIST} | |
| ${FNAME}" | |
| fi | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| done | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_properties_options() { | |
| # | |
| # This function gets any configuration options required for | |
| # the file properties check and the properties file update. | |
| # | |
| # For options where filenames are specified, the existence | |
| # of the filename is checked. | |
| # | |
| check_test hashes && HASH_CHECK_ENABLED=1 | |
| check_test attributes && HASH_CHECK_ENABLED=1 | |
| LEAVE=0 | |
| ERRCODE=0 | |
| ATTRWHITELIST="" | |
| ATTRWL_OPT=`get_option newline-list ATTRWHITELIST` || exit $? | |
| if [ -n "${ATTRWL_OPT}" ]; then | |
| ATTRWHITELIST=`expand_paths ATTRWL_OPT` | |
| check_paths ATTRWHITELIST ATTRWHITELIST "EXIST" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| WRITEWHITELIST="" | |
| WRITEWL_OPT=`get_option newline-list WRITEWHITELIST` || exit $? | |
| if [ -n "${WRITEWL_OPT}" ]; then | |
| WRITEWHITELIST=`expand_paths WRITEWL_OPT` | |
| check_paths WRITEWHITELIST WRITEWHITELIST "EXIST" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| IMMUTWHITELIST="" | |
| IMMUTWL_OPT=`get_option newline-list IMMUTWHITELIST` || exit $? | |
| if [ -n "${IMMUTWL_OPT}" ]; then | |
| IMMUTWHITELIST=`expand_paths IMMUTWL_OPT` | |
| check_paths IMMUTWHITELIST IMMUTWHITELIST "EXIST" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| IMMUTABLE_SET=`get_option single IMMUTABLE_SET` || exit $? | |
| if [ -n "${IMMUTABLE_SET}" ]; then | |
| check_is_digit IMMUTABLE_SET | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| IMMUTABLE_SET=0 | |
| fi | |
| SCRIPTWHITELIST="" | |
| SCRIPTWL_OPT=`get_option newline-list SCRIPTWHITELIST` || exit $? | |
| if [ -n "${SCRIPTWL_OPT}" ]; then | |
| SCRIPTWHITELIST=`expand_paths SCRIPTWL_OPT` | |
| check_paths SCRIPTWHITELIST SCRIPTWHITELIST "EXIST" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| SKIP_INODE_CHECK=`get_option single SKIP_INODE_CHECK` || exit $? | |
| if [ -n "${SKIP_INODE_CHECK}" ]; then | |
| check_is_digit SKIP_INODE_CHECK | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SKIP_INODE_CHECK=0 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_prelink_dep_option() { | |
| # | |
| # This function gets the prelink dependency error option. | |
| # This option is a workaround for any files which persistently | |
| # give a prelinking dependency error. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| RKHTMPVAR=`get_option space-list IGNORE_PRELINK_DEP_ERR` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR=`make_space_list "${RKHTMPVAR}"` | |
| check_paths RKHTMPVAR IGNORE_PRELINK_DEP_ERR "EXIST NOWILD NOBROKENLINK" | |
| if [ $ERRCODE -eq 0 ]; then | |
| PRELINK_DEP_ERR_CMDS=" ${RKHTMPVAR} " | |
| else | |
| LEAVE=1 | |
| fi | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_summary_options() { | |
| # | |
| # Get the configuration options for the summary. | |
| # | |
| # | |
| # Get the option to see if we are to show the | |
| # actual number of warnings in the summary. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| SHOW_SUMMARY_WARNINGS_NUMBER=`get_option single SHOW_SUMMARY_WARNINGS_NUMBER` || exit $? | |
| if [ -n "${SHOW_SUMMARY_WARNINGS_NUMBER}" ]; then | |
| check_is_digit SHOW_SUMMARY_WARNINGS_NUMBER | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| else | |
| SHOW_SUMMARY_WARNINGS_NUMBER=0 | |
| fi | |
| # | |
| # Get the option to see where, if at all, | |
| # we are to show the summary scan time. | |
| # | |
| SHOW_SUMMARY_TIME=`get_option single SHOW_SUMMARY_TIME` || exit $? | |
| if [ -n "${SHOW_SUMMARY_TIME}" ]; then | |
| check_is_digit SHOW_SUMMARY_TIME SHOW_SUMMARY_TIME ANY | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ $SHOW_SUMMARY_TIME -gt 3 ]; then | |
| LEAVE=1 | |
| echo "Invalid SHOW_SUMMARY_TIME configuration option: not a valid number: ${SHOW_SUMMARY_TIME}" | |
| fi | |
| else | |
| LEAVE=1 | |
| fi | |
| else | |
| SHOW_SUMMARY_TIME=3 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_network_options() { | |
| # | |
| # Get any options used for network tests. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| IFWLIST=`get_option space-list ALLOWPROMISCIF` || exit $? | |
| ALLOWPROCLIST_OPT=`get_option newline-list ALLOWPROCLISTEN` || exit $? | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_os_specific_options() { | |
| # | |
| # Get any O/S specific options. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| if [ $LINUXOS -eq 1 ]; then | |
| LKM_PATH=`get_option single MODULES_DIR` || exit $? | |
| if [ -z "${LKM_PATH}" ]; then | |
| LKM_PATH="/lib/modules/${UNAME_R}" | |
| test ! -d "${LKM_PATH}" && LKM_PATH="/lib/modules" | |
| fi | |
| check_paths LKM_PATH MODULES_DIR "NOBROKENLINK NOWILD" | |
| test $ERRCODE -eq 1 && LEAVE=1 | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_app_options() { | |
| # | |
| # Get any options used for the application check. | |
| # | |
| LEAVE=0 | |
| ERRCODE=0 | |
| APP_WHITELIST="" | |
| RKHTMPVAR=`get_option space-list APP_WHITELIST` || exit $? | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR=`echo ${RKHTMPVAR}` | |
| APP_WHITELIST=`echo " ${RKHTMPVAR} " | tr '[:upper:]' '[:lower:]'` | |
| fi | |
| if [ $LEAVE -eq 1 ]; then | |
| if [ $CONFIG_CHECK -eq 0 ]; then | |
| exit 1 | |
| else | |
| RET_CODE=1 | |
| fi | |
| fi | |
| return | |
| } | |
| get_configfile_options() { | |
| # | |
| # We call separate functions to process each option. The option | |
| # is checked first to see if it has been given on the command-line, | |
| # and, if not, then if it is specified in the configuration file. | |
| # Note that some of these functions are in a specific order. If you | |
| # change them around, then make sure the functions still work | |
| # correctly. | |
| # | |
| get_bindir_option | |
| get_scriptdir_option | |
| # | |
| # Now that we have processed BINDIR, we will recheck the required | |
| # commands. | |
| # | |
| # Before proceeding too far we also check that we have certain | |
| # commands available. Typically these are commands which might | |
| # not have been installed as part of the core system, but are | |
| # used by RKH. These commands are not 'required' though. | |
| # | |
| check_required_commands 2 | |
| check_commands | |
| get_installdir_option | |
| get_rootdir_option | |
| get_logfile_option | |
| get_tmpdir_option | |
| get_dbdir_option | |
| get_language_option | |
| get_auto_x_option | |
| get_locking_options | |
| get_shell_options | |
| # | |
| # Some options are only required when checking the system. | |
| # | |
| if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| # | |
| # See if we are only to perform specific tests. | |
| # | |
| get_enable_option | |
| get_disable_option | |
| check_test_options | |
| get_existwl_option | |
| fi | |
| if [ $CHECK -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| get_scanmode_option | |
| get_syslog_option | |
| get_startup_paths_option | |
| get_rtkt_whitelist_options | |
| get_epoch_date_cmd_option | |
| get_phalanx2_option | |
| get_summary_options | |
| get_ipc_options | |
| test $NOMOW -eq 0 && get_mailonwarn_option | |
| if `check_test system_configs`; then | |
| get_ssh_options | |
| get_syslog_config_options | |
| fi | |
| if `check_test filesystem`; then | |
| get_scan_mode_dev_option | |
| get_missing_file_options | |
| get_hidden_options | |
| get_dev_options | |
| fi | |
| check_test trojans && get_xinetd_option | |
| check_test ports || check_test hidden_ports && get_port_options | |
| check_test group_accounts && get_groups_accounts_options | |
| check_test shared_libs && get_shared_lib_whitelist_option | |
| check_test hidden_procs || check_test hidden_ports && get_unhide_options | |
| check_test deleted_files && get_process_options | |
| check_test suspscan && get_suspscan_options | |
| check_test network && get_network_options | |
| check_test os_specific && get_os_specific_options | |
| check_test apps && get_app_options | |
| fi | |
| # | |
| # We only need the hash function option if we are going | |
| # to be checking the system or updating the file | |
| # properties database. | |
| # | |
| if `check_test properties` || test $PROP_UPDATE -eq 1 || test $CONFIG_CHECK -eq 1; then | |
| # | |
| # For the file properties check we need to find out if | |
| # we are a prelinked system, and if so, then find out | |
| # which hash function to use. Secondly, we need to find | |
| # the 'stat' command. Finally, we need to see if the | |
| # user has specified any files or directories for the | |
| # file properties check. | |
| # | |
| get_if_prelinked | |
| get_hash_function | |
| get_os_info_options | |
| get_user_fileprop_list | |
| get_properties_options | |
| fi | |
| # | |
| # If we are doing a file properties update, then we need to | |
| # see if we should be ignoring prelink errors for any files. | |
| # | |
| if [ $PROP_UPDATE -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| get_prelink_dep_option | |
| fi | |
| # | |
| # Get any set options when doing an update or version check. | |
| # | |
| if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 -o $CONFIG_CHECK -eq 1 ]; then | |
| get_mirror_options | |
| get_webcmd_option | |
| fi | |
| return | |
| } | |
| get_readable_date() { | |
| # | |
| # This function returns a given epoch second time as a | |
| # human-readable date and time. It sets the READABLE_DATE | |
| # variable. | |
| # | |
| EPOCH_SECS=$1 | |
| READABLE_DATE="" | |
| if [ "${EPOCH_DATE_CMD}" = "NONE" ]; then | |
| : | |
| elif [ -n "${EPOCH_DATE_CMD}" ]; then | |
| EPOCH_NOW=`${EPOCH_DATE_CMD} '+%s'` | |
| EPOCH_SECS=`expr $EPOCH_NOW - $EPOCH_SECS` | |
| READABLE_DATE=`${EPOCH_DATE_CMD} --date "$EPOCH_SECS seconds ago" '+%d-%b-%Y %H:%M:%S' 2>/dev/null` | |
| elif [ -n "${PERL_CMD}" ]; then | |
| READABLE_DATE=`${PERL_CMD} -e "@a=split(' ',scalar(localtime($EPOCH_SECS))); printf \"%d-%s-%d %s\",\\$a[2],\\$a[1],\\$a[4],\\$a[3];" 2>/dev/null` | |
| fi | |
| return | |
| } | |
| rkh_dat_set_version() { | |
| # | |
| # This function calculates and writes out the 'Version:' value | |
| # for the rkhunter.dat file. It looks for an old value, and adds | |
| # one to it. If there is no value then simply start at zero. | |
| # | |
| # Note that the new temporary rkhunter.dat file is used. | |
| # | |
| TODAY=`date +%Y%m%d 2>/dev/null` | |
| OLDVER=`grep '^[Vv]ersion:' "${RKHDAT_FILE}" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f2` | |
| if [ -n "${OLDVER}" ]; then | |
| OLDDATE=`echo "${OLDVER}" | cut -c1-8` | |
| OLDVER=`echo "${OLDVER}" | cut -c9-10` | |
| if [ "${OLDVER}" = "99" -o "${OLDDATE}" != "${TODAY}" -o -z "${OLDVER}" -o -n "`echo \"${OLDVER}\" | grep '[^0-9]'`" ]; then | |
| NEWVER="00" | |
| else | |
| NEWVER=`expr ${OLDVER} + 1` | |
| test $NEWVER -lt 10 && NEWVER="0${NEWVER}" | |
| fi | |
| else | |
| NEWVER="00" | |
| fi | |
| echo "Version:${TODAY}${NEWVER}" >>"${RKHDAT_TMPFILE}" | |
| return | |
| } | |
| rkh_dat_get_os_info() { | |
| # | |
| # This function obtains information about the local computer | |
| # system. This is then written into the rkhunter.dat file | |
| # using a simple 'keyword:<value>' format. The OSNAME and | |
| # ARCH values are not important, but are simply used to check | |
| # whether they have changed since RKH was last run. | |
| # | |
| # Obtaining the OSNAME is somewhat tricky. There is no sure | |
| # way of finding the information, so we have to use some tricks | |
| # to locate the correct file. First we look for certain specific | |
| # O/S release files, and then at the /etc/release file, but not | |
| # if it is a link. Next we look for a generic /etc/*-release | |
| # file, again not as a link. This should find most O/S versions. | |
| # Overall this should also save users having to ask us to support | |
| # their O/S. In other cases, we will have to ask what file does | |
| # contain their O/S release information. | |
| # | |
| ARCH="" | |
| OSNAME="" | |
| RELEASE="" | |
| UNAME_S=`uname -s 2>/dev/null` | |
| UNAME_M=`uname -m 2>/dev/null` | |
| if [ -n "${OS_VERSION_FILE}" ]; then | |
| REL_FILES="${OS_VERSION_FILE}" | |
| else | |
| REL_FILES="/etc/system-release /etc/os-release /usr/lib/os-release /etc/lsb-release /etc/debian_version /etc/devuan_version /etc/slackware-version /var/ipcop/general-functions.pl /etc/lunar.release /etc/ROCK-VERSION /etc/GoboLinuxVersion /etc/kanotix-version /etc/sidux-version /etc/knoppix-version /etc/zenwalk-version /etc/release /etc/*-release" | |
| fi | |
| RKH_LSB_SEEN=0 | |
| for FNAME in ${REL_FILES}; do | |
| test ! -f "${FNAME}" && continue | |
| if [ "${FNAME}" = "/etc/system-release" ]; then | |
| RKH_IN_LSB=0 | |
| RELEASE=$FNAME | |
| OSNAME=`cat "${FNAME}"` | |
| break | |
| elif [ ! -h "${FNAME}" ]; then | |
| RELEASE=$FNAME | |
| RKH_IN_LSB=0 | |
| case "${RELEASE}" in | |
| /etc/os-release|/usr/lib/os-release) | |
| OSNAME=`grep '^PRETTY_NAME=' "${RELEASE}" | sed -e 's/PRETTY_NAME=//' | tr -d '"'` | |
| if [ -z "${OSNAME}" ]; then | |
| RKHTMPVAR=`grep '^NAME=' "${RELEASE}" | sed -e 's/NAME=//'`; | |
| RKHTMPVAR2=`grep '^VERSION=' "${RELEASE}" | sed -e 's/VERSION=//' | tr -d '"'`; | |
| if [ -z "${RKHTMPVAR2}" ]; then | |
| RKHTMPVAR2=`grep '^VERSION_ID=' "${RELEASE}" | sed -e 's/VERSION_ID=//' | tr -d '"'`; | |
| fi | |
| OSNAME="${RKHTMPVAR} ${RKHTMPVAR2}" | |
| fi | |
| ;; | |
| /etc/lsb-release) | |
| RKH_IN_LSB=1 | |
| RKH_LSB_SEEN=1 | |
| OSNAME=`grep '^DISTRIB_DESCRIPTION=' "${RELEASE}" | sed -e 's/DISTRIB_DESCRIPTION=//' | tr -d '"'` | |
| ;; | |
| /etc/gentoo-release) | |
| if [ -h "/etc/make.profile" ]; then | |
| OSNAME="Gentoo `ls -l /etc/make.profile 2>/dev/null | sed -e 's;^.*/\([^/]*/[^/]*\)$;\1;' | tr '/' ' '`" | |
| else | |
| OSNAME="Gentoo" | |
| fi | |
| ;; | |
| /var/ipcop/general-functions.pl) | |
| OSNAME=`grep 'version *=' "${RELEASE}" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| /etc/debian_version) | |
| OSNAME="Debian `cat \"${RELEASE}\"`" | |
| ;; | |
| /etc/devuan_version) | |
| OSNAME="Devuan `cat \"${RELEASE}\"`" | |
| ;; | |
| /etc/GoboLinuxVersion) | |
| OSNAME="GoboLinux `cat \"${RELEASE}\"`" | |
| ;; | |
| /etc/knoppix-version) | |
| OSNAME="Knoppix `cat \"${RELEASE}\"`" | |
| ;; | |
| /etc/zenwalk-version) | |
| OSNAME="Zenwalk `cat \"${RELEASE}\"`" | |
| ;; | |
| *) | |
| OSNAME=`${AWK_CMD} '/^[ ]*[^ ]/ { print $0 }' "${RELEASE}" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| esac | |
| # | |
| # Strip out any leading blanks and tabs from the O/S version. | |
| # | |
| test -n "${OSNAME}" && OSNAME=`echo ${OSNAME}` | |
| # | |
| # If we have a release file but it seems to be blank, | |
| # and we are not looking at the LSB release file, then | |
| # we take a look for the first non-blank line. We | |
| # then, again, strip out any leading blanks and tabs. | |
| # | |
| if [ $RKH_IN_LSB -eq 0 -a -z "${OSNAME}" ]; then | |
| OSNAME=`${AWK_CMD} '/^[ ]*[^ ]/ { print $0 }' "${RELEASE}" 2>/dev/null | head ${HEAD_OPT}1` | |
| OSNAME=`echo ${OSNAME}` | |
| fi | |
| test -n "${OSNAME}" && break | |
| fi | |
| done | |
| if [ -z "${OSNAME}" ]; then | |
| RELEASE="" | |
| if [ -d "/var/smoothwall" ]; then | |
| OSNAME="Smoothwall Linux" | |
| RELEASE="/var/smoothwall" | |
| elif [ -n "`which sorcery 2>/dev/null | grep -v ' '`" -a -n "`which gaze 2>/dev/null | grep -v ' '`" ]; then | |
| OSNAME="Source Mage Linux" | |
| fi | |
| fi | |
| case "${OPERATING_SYSTEM}" in | |
| SunOS) | |
| ARCH=`uname -p 2>/dev/null` | |
| ;; | |
| FreeBSD|DragonFly) | |
| ARCH=`sysctl -n hw.machine_arch 2>/dev/null` | |
| OSNAME=`uname -v 2>/dev/null | cut -d' ' -f1,2` | |
| ;; | |
| OpenBSD) | |
| OSNAME="OpenBSD ${UNAME_R}" | |
| ;; | |
| Darwin) | |
| OSNAME=`sw_vers 2>/dev/null | grep '^ProductName:' | sed -e 's/ProductName:[ ]*//'` | |
| OSNAME="${OSNAME} `sw_vers 2>/dev/null | grep '^ProductVersion:' | sed -e 's/ProductVersion:[ ]*//'`" | |
| # OSNAME="${OSNAME} `sysctl kern.version 2>/dev/null | sed -e 's/^kern.version = //' | cut -d: -f1`" | |
| if [ -n "`sysctl -a 2>/dev/null | grep -E '^(hw\.optional\.x86_64|hw\.optional\.64bitops|hw\.cpu64bit_capable).*1$'`" ]; then | |
| OSNAME="${OSNAME} (64-bit capable)" | |
| fi | |
| ;; | |
| AIX) | |
| ARCH=`uname -p 2>/dev/null` | |
| OSNAME="IBM AIX `oslevel 2>/dev/null`" | |
| ;; | |
| IRIX*) | |
| OSNAME="${OPERATING_SYSTEM} ${UNAME_R}" | |
| ;; | |
| esac | |
| # | |
| # If the O/S name seems to be a string of numbers, then forget we saw it. | |
| # | |
| test -n "`echo \"${OSNAME}\" | grep '^[0-9._-][0-9._-]*$'`" && OSNAME="" | |
| # | |
| # If we still have no O/S version information, then as a last | |
| # resort we will look to see if an 'issue' file exists or use | |
| # whatever is in the LSB release file. We test these last because | |
| # they are not necessarily reliable in providing the O/S version. | |
| # | |
| if [ -z "${OSNAME}" ]; then | |
| if [ -f "/etc/issue" ]; then | |
| OSNAME=`${AWK_CMD} '/^[ ]*[^ \\\]/ { print $0 }' /etc/issue 2>/dev/null | head ${HEAD_OPT}1` | |
| # | |
| # Modify or remove the escape sequences seen in the file. | |
| # | |
| OSNAME=`echo "${OSNAME}" | sed -e "s/\\\\\s/${UNAME_S}/g; s/\\\\\r/${UNAME_R}/g; s/\\\\\m/${UNAME_M}/g"` | |
| OSNAME=`echo "${OSNAME}" | sed -e 's/ (*\\\[^ ]*//g'` | |
| OSNAME=`echo ${OSNAME}` | |
| test -n "${OSNAME}" && RELEASE="/etc/issue" | |
| fi | |
| if [ $RKH_LSB_SEEN -eq 1 -a -z "${OSNAME}" ]; then | |
| OSNAME=`${AWK_CMD} '/^[ ]*[^ ]/ { print $0 }' /etc/lsb-release 2>/dev/null | head ${HEAD_OPT}1` | |
| OSNAME=`echo ${OSNAME}` | |
| test -n "${OSNAME}" && RELEASE="/etc/lsb-release" | |
| fi | |
| fi | |
| # | |
| # If some things have still not been set, then set them now. | |
| # | |
| test -z "${ARCH}" && ARCH="${UNAME_M}" | |
| test -z "${OSNAME}" && OSNAME="`uname` ${UNAME_R}" | |
| return | |
| } | |
| rkh_dat_set_file_properties() { | |
| # | |
| # This function obtains various bits of information about the files to | |
| # be checked. The current format in the rkhunter.dat file is: | |
| # | |
| # File:<colon count>:<pathname>:<hash value>:<inode>:<permissions>: | |
| # <uid>:<gid>:<file size>:<date/time modified>:<package name>: | |
| # <symbolic link colon count>:<symbolic link target> | |
| # | |
| # The format is actually governed by the stat.pl file, and the output | |
| # it produces. Changing the order of options does not change the order | |
| # of the output. | |
| # | |
| # To save time in the loops below, we determine the exact commands | |
| # required before using them. | |
| # | |
| NODATFILE=0 | |
| NOHASH_COUNT=0 | |
| BROKEN_LINK_COUNT=0 | |
| PROP_FILE_LIST_COUNT=0 | |
| PROP_FILE_PROPOPT_COUNT=0 | |
| DIR_FILE_COUNT="" | |
| display --to LOG --type PLAIN SET_FILE_PROP_START | |
| if ! `check_test attributes` && test $ENDIS_OPT -eq 0; then | |
| SCMD="" | |
| INODECMD="" | |
| elif [ -z "${STAT_CMD}" ]; then | |
| SCMD="" | |
| INODECMD="" | |
| else | |
| if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then | |
| if [ "${PKGMGR}" = "SOLARIS" ]; then | |
| SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --mtime" | |
| else | |
| SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --Mtime" | |
| fi | |
| INODECMD="${STAT_CMD} --modeoct --raw --ino" | |
| elif [ $BSDOS -eq 1 -o $MACOSX -eq 1 ]; then | |
| SCMD="${STAT_CMD} -f '%i %Mp%Lp %u %g %z %m:'" | |
| INODECMD="${STAT_CMD} -f '%i'" | |
| else | |
| SCMD="${STAT_CMD} -c '%i 0%a %u %g %s %Y:'" | |
| INODECMD="${STAT_CMD} -c '%i'" | |
| fi | |
| fi | |
| if ! `check_test hashes` && test $ENDIS_OPT -eq 0; then | |
| HASH_CMD="" | |
| elif [ -z "${PKGMGR}" -a "${HASH_FUNC}" = "NONE" ]; then | |
| HASH_CMD="" | |
| else | |
| HASH_CMD="${HASH_FUNC}" | |
| fi | |
| # | |
| # Next dig out the old file format version. We may need this if | |
| # we are only updating one file and the format has changed. | |
| # | |
| if [ -s "${RKHDAT_FILE}" ]; then | |
| OLD_FMTVERSION=`grep '^FormatVersion:' "${RKHDAT_FILE}" 2>/dev/null | cut -d: -f2` | |
| test -z "${OLD_FMTVERSION}" && OLD_FMTVERSION=0 | |
| else | |
| NODATFILE=1 | |
| fi | |
| # | |
| # Now loop through the pathnames looking for the files. | |
| # | |
| # We must set IFS around this loop, otherwise any names in the file | |
| # properties list containing whitespace will be separated out. | |
| # However, because IFS interacts with some commands, executed via | |
| # backticks, we must then reset IFS for the duration of the loop | |
| # and set it again at the end of the loop. It's messy, but it works. | |
| # | |
| IFS=$IFSNL | |
| for FNAME in `cat "${RKH_FILEPROP_LIST}"`; do | |
| test ! -f "${FNAME}" -a ! -h "${FNAME}" && continue | |
| FDATA="" | |
| SYSLNK="" | |
| SYSHASH="" | |
| PKGNAME="" | |
| FNAMEGREP="" | |
| RPM_QUERY_RESULT="" | |
| SYSLNK_CC=0 | |
| NOVRFYFILE=0 | |
| COLON_COUNT=0 | |
| FILE_IS_PKGD=0 | |
| DEPENDENCY_ERR=0 | |
| IFS=$RKHIFS | |
| PROP_FILE_LIST_COUNT=`expr ${PROP_FILE_LIST_COUNT} + 1` | |
| # | |
| # Set up some variables here based on the file name. We will | |
| # need them later on. | |
| # | |
| COLON_COUNT=`echo "${FNAME}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| # | |
| # Test to see if we are looking for specific files or not. | |
| # | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| # | |
| # If we are looking for specific files, then just copy the | |
| # entries from the current rkhunter.dat file for the files | |
| # we aren't looking for. For the ones we do want, we fall | |
| # through and process them as before. | |
| # | |
| if [ $NODATFILE -eq 0 ]; then | |
| if [ -z "`echo \"${PROPUPD_OPT}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $OLD_FMTVERSION -eq 0 ]; then | |
| RKHTMPVAR=`grep "^File:${FNAMEGREP}:" "${RKHDAT_FILE}"` | |
| else | |
| RKHTMPVAR=`grep "^File:${COLON_COUNT}:${FNAMEGREP}:" "${RKHDAT_FILE}"` | |
| fi | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| echo "${RKHTMPVAR}" >>"${RKHDAT_TMPFILE}" | |
| IFS=$IFSNL | |
| continue | |
| fi | |
| fi | |
| fi | |
| PROP_FILE_PROPOPT_COUNT=`expr ${PROP_FILE_PROPOPT_COUNT} + 1` | |
| fi | |
| # | |
| # Sort out the directory counters. | |
| # | |
| test -n "${DIRNAME_CMD}" && DIR=`${DIRNAME_CMD} "${FNAME}"` || DIR=`echo "${FNAME}" | sed -e 's:/[^/]*$::'` | |
| RKHTMPVAR2=`echo "${DIR}" | sed -e 's/\./\\\./g'` | |
| RKHTMPVAR=`echo "${DIR_FILE_COUNT}" | grep "^${RKHTMPVAR2}:"` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| DIR_FILE_COUNT="${DIR_FILE_COUNT} | |
| ${DIR}:1" | |
| else | |
| RKHTMPVAR=`echo ${RKHTMPVAR} | sed -e 's/^.*:\([0-9]*\)$/\1/'` | |
| RKHTMPVAR=`expr ${RKHTMPVAR} + 1` | |
| DIR_FILE_COUNT=`echo "${DIR_FILE_COUNT}" | sed -e "s;^\(${DIR}:\).*;\1${RKHTMPVAR};"` | |
| fi | |
| # | |
| # See if the file is to be exempt from any package manager verification. | |
| # | |
| if [ -n "`echo \"${PKGMGRNOVRFY}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| NOVRFYFILE=1 | |
| fi | |
| # | |
| # Now start to get the file info by seeing if we are using a | |
| # package manager. If we are, then get the package name and | |
| # any other info we can except the hash value. That will be | |
| # dealt with afterwards. | |
| # | |
| case "${PKGMGR}" in | |
| RPM) | |
| # | |
| # First see if the file is exempt or belongs to a package. | |
| # | |
| if [ $NOVRFYFILE -eq 0 ]; then | |
| RKHTMPVAR=`${RPM_CMD} -qf "${FNAME}" --queryformat '%{NAME}\n' 2>/dev/null` | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Okay we have a package name. | |
| # | |
| FILE_IS_PKGD=1 | |
| PKGNAME=`echo "${RKHTMPVAR}" | tail ${TAIL_OPT}1` | |
| RPM_QUERY_RESULT_ARCH=`${RPM_CMD} -qf --queryformat '[%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{=ARCH}:%{FILELINKTOS}:%{FILENAMES}\n]' "${FNAME}" 2>/dev/null | grep ":${FNAMEGREP}\$"` | |
| ERRCODE=$? | |
| # | |
| # The error code actually refers to the 'grep' command above. If the | |
| # file is not found in the package, then this is probably due to the | |
| # 'bin' directory being a link. So we change the filename, and retest. | |
| # | |
| if [ $ERRCODE -eq 1 -a $BINISLINK -eq 1 ]; then | |
| if [ -n "`echo \"$FNAME\" | grep '^\/usr\/'`" ]; then | |
| RKHTMPVAR3=`echo "$FNAMEGREP" | sed -e 's:^/usr::'` | |
| else | |
| RKHTMPVAR3="/usr${FNAMEGREP}" | |
| fi | |
| RPM_QUERY_RESULT_ARCH=`${RPM_CMD} -qf --queryformat '[%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{=ARCH}:%{FILELINKTOS}:%{FILENAMES}\n]' "${FNAME}" 2>/dev/null | grep ":${RKHTMPVAR3}\$"` | |
| ERRCODE=$? | |
| fi | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # If multiple packages claim the same file, we | |
| # use the last one in the list. However, if we | |
| # have 64-bit as well as 32-bit packages, then | |
| # we use the 64-bit package in preference (as | |
| # this is what RPM does). | |
| # | |
| RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT_ARCH}" | grep -E ':(x86_64|ia64):' 2>/dev/null | tail ${TAIL_OPT}1` | |
| test -z "${RPM_QUERY_RESULT}" && RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT_ARCH}" | tail ${TAIL_OPT}1` | |
| FPERM="0`echo \"${RPM_QUERY_RESULT}\" | cut -d: -f1 | cut -c 3-`" | |
| FPERM=`echo "${FPERM}" | sed -e 's/^00/0/'` | |
| RKHUID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f2` | |
| RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3` | |
| RKHGID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f3` | |
| RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3` | |
| RKHSIZE=`echo "${RPM_QUERY_RESULT}" | cut -d: -f4` | |
| RKHDTM=`echo "${RPM_QUERY_RESULT}" | cut -d: -f5` | |
| if [ -h "${FNAME}" ]; then | |
| test -n "${DIRNAME_CMD}" && DIR=`${DIRNAME_CMD} "${FNAME}"` || DIR=`echo "${FNAME}" | sed -e 's:/[^/]*$::'` | |
| SYSLNK=`echo "${RPM_QUERY_RESULT}" | cut -d: -f8` | |
| SYSLNK="${DIR}/${SYSLNK}" | |
| # This ensures the link target has things like '..' removed. | |
| test $HAVE_READLINK -eq 1 && SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${SYSLNK}"` | |
| fi | |
| # | |
| # Now get the inode value directly from the disk, | |
| # but only if prelinking is not being used. | |
| # | |
| RKHTMPVAR2="" | |
| if [ $PRELINKED -eq 0 -a -n "${INODECMD}" ]; then | |
| RKHTMPVAR2=`eval ${INODECMD} "\"${FNAME}\"" 2>/dev/null | tr -d ' '` | |
| fi | |
| FDATA="${RKHTMPVAR2}:${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}" | |
| else | |
| NOHASH_COUNT=`expr $NOHASH_COUNT + 1` | |
| display --to LOG --type INFO CMD_ERROR "rpm -qf --queryformat... ${FNAME}" $ERRCODE | |
| fi | |
| fi | |
| fi | |
| ;; | |
| DPKG) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| ERRCODE=1 | |
| else | |
| RKHTMPVAR=`${DPKG_CMD} --search "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| fi | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Now we sort out the base part of the package name. | |
| # | |
| PKGNAME=`echo "${RKHTMPVAR}" | tail ${TAIL_OPT}1 | cut -d: -f1` | |
| fi | |
| ;; | |
| BSD) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| PKGNAME="" | |
| if [ $NOVRFYFILE -eq 0 ]; then | |
| RKHTMPVAR=`${PKG_CMD} -F -e "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| if [ $ERRCODE -ne 0 ]; then | |
| # | |
| # It may be that we need to use the '-W' option instead. | |
| # | |
| RKHTMPVAR=`${PKG_CMD} -q -W "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| fi | |
| if [ $ERRCODE -eq 0 -a -n "${RKHTMPVAR}" ]; then | |
| PKGNAME=`echo "${RKHTMPVAR}" | tail ${TAIL_OPT}1` | |
| fi | |
| fi | |
| ;; | |
| BSDNG) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| ERRCODE=1 | |
| else | |
| RKHTMPVAR=`${PKG_CMD} which -q "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| fi | |
| test $ERRCODE -eq 0 && PKGNAME="${RKHTMPVAR}" || PKGNAME="" | |
| ;; | |
| SOLARIS) | |
| # | |
| # First see if the file is exempt or belongs to a package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| ERRCODE=1 | |
| else | |
| RKHTMPVAR=`grep "^${FNAMEGREP} " /var/sadm/install/contents 2>/dev/null` | |
| test -n "${RKHTMPVAR}" && ERRCODE=0 || ERRCODE=1 | |
| fi | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Okay we have a package name. | |
| # | |
| PKGNAME=`echo "${RKHTMPVAR}" | cut -d' ' -f10-` | |
| FPERM=`echo "${RKHTMPVAR}" | cut -d' ' -f4` | |
| RKHUID=`echo "${RKHTMPVAR}" | cut -d' ' -f5` | |
| RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3` | |
| RKHGID=`echo "${RKHTMPVAR}" | cut -d' ' -f6` | |
| RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3` | |
| RKHSIZE=`echo "${RKHTMPVAR}" | cut -d' ' -f7` | |
| if [ $USE_SUNSUM -eq 1 ]; then | |
| # Treat this as a fully packaged file. | |
| FILE_IS_PKGD=1 | |
| SYSHASH=`echo "${RKHTMPVAR}" | cut -d' ' -f8` | |
| fi | |
| RKHDTM=`echo "${RKHTMPVAR}" | cut -d' ' -f9` | |
| # | |
| # Now get the inode value. | |
| # | |
| RKHTMPVAR2="" | |
| test -n "${INODECMD}" && RKHTMPVAR2=`eval ${INODECMD} "\"${FNAME}\"" 2>/dev/null | tr -d ' '` | |
| FDATA="${RKHTMPVAR2}:${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}" | |
| fi | |
| ;; | |
| esac | |
| if [ -n "${HASH_CMD}" ]; then | |
| if [ -n "`echo \"${PRELINK_DEP_ERR_CMDS}\" | grep \" ${FNAMEGREP} \"`" ]; then | |
| FILE_IS_PKGD=1 | |
| SYSHASH="ignore-prelink-dep-err" | |
| display --to LOG --type INFO FILE_PROP_IGNORE_PRELINK_DEP_ERR "`name2text \"${FNAME}\"`" | |
| else | |
| case "${PKGMGR}" in | |
| RPM) | |
| test $FILE_IS_PKGD -eq 1 && SYSHASH=`echo "${RPM_QUERY_RESULT}" | cut -d: -f6` | |
| ;; | |
| DPKG) | |
| # | |
| # If we have a package name, then strip off the leading | |
| # '/' from the pathname, and then get the hash value. | |
| # | |
| if [ -n "${PKGNAME}" ]; then | |
| if [ -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then | |
| FILNAM=`echo "${FNAME}" | sed -e 's:^/::; s:\.:\\\.:g'` | |
| SYSHASH=`grep -E "( |\./)${FILNAM}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" 2>/dev/null | cut -d' ' -f1` | |
| test -n "${SYSHASH}" && FILE_IS_PKGD=1 | |
| fi | |
| fi | |
| ;; | |
| BSD) | |
| # | |
| # If we have a package name, then strip off the leading '/usr/pkg/' or | |
| # '/usr/local/' from the pathname, and then get the hash value. | |
| # | |
| if [ -n "${PKGNAME}" ]; then | |
| FILNAM=`echo "${FNAME}" | sed -e 's:^/usr/pkg/::; s:^/usr/local/::; s:\.:\\\.:g'` | |
| SYSHASH=`${PKG_CMD} -v -L "${PKGNAME}" 2>/dev/null | grep -A 1 "File: ${FILNAM}\$" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f3` | |
| test -n "${SYSHASH}" && FILE_IS_PKGD=1 | |
| fi | |
| ;; | |
| BSDNG) | |
| # | |
| # If we have a package name, then get the hash value. | |
| # | |
| if [ -n "${PKGNAME}" ]; then | |
| SYSHASH=`${PKG_CMD} query '%Fp: %Fs' ${PKGNAME} 2>/dev/null | grep "^${FNAME}: " 2>/dev/null | sed -r -e 's/^.*: (1\\$)?([A-Fa-f0-9]+)$/\2/'` | |
| test -n "${SYSHASH}" && FILE_IS_PKGD=1 | |
| fi | |
| ;; | |
| SOLARIS) | |
| # | |
| # If we are to use the stored 16-bit checksum, then | |
| # SYSHASH will already have been set above. Otherwise, | |
| # just calculate the hash as for non-packaged files. | |
| # | |
| ;; | |
| esac | |
| fi | |
| if [ $FILE_IS_PKGD -eq 0 ]; then | |
| if [ "${HASH_CMD}" != "NONE" ]; then | |
| SYSHASH="" | |
| RKHTMPVAR=`${HASH_CMD} "${FNAME}" 2>&1` | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | tr '\n' ':' | sed -e 's/:$//'` | |
| else | |
| SYSHASH=`echo "${RKHTMPVAR}" | cut -d' ' -f $HASH_FLD_IDX | grep '^[0-9a-fA-F]*$'` | |
| fi | |
| fi | |
| if [ -z "${SYSHASH}" ]; then | |
| if [ "${HASH_CMD}" = "NONE" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_NO_PKGMGR_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| elif [ -h "${FNAME}" -a ! -e "${FNAME}" ]; then | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| RKHTMPVAR="${SYSLNK}" | |
| RKHTMPVAR2=`echo "${SYSLNK}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| else | |
| RKHTMPVAR="" | |
| fi | |
| # Check the link target to see if it is whitelisted. | |
| if [ $HAVE_READLINK -eq 1 -a -n "`echo \"${EXISTWHITELIST}\" | grep \"^${RKHTMPVAR2}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_BROKEN_LINK_WL_TGT "`name2text \"${FNAME}\"`" "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| # Treat a broken link simply as a file with no hash. | |
| BROKEN_LINK_COUNT=`expr ${BROKEN_LINK_COUNT} + 1` | |
| display --to LOG --type WARNING FILE_PROP_NO_SYSHASH "`name2text \"${FNAME}\"`" | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_BL "`name2text \"${FNAME}\"`" "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| NOHASH_COUNT=`expr ${NOHASH_COUNT} + 1` | |
| display --to LOG --type WARNING FILE_PROP_NO_SYSHASH "`name2text \"${FNAME}\"`" | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_CMD "${RKHTMPVAR}" | |
| if [ $DEPENDENCY_ERR -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "`name2text \"${FNAME}\"`" | |
| fi | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ -h "${FNAME}" -a -z "${SYSLNK}" ]; then | |
| test $HAVE_READLINK -eq 1 && SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| if [ -z "${SCMD}" ]; then | |
| FDATA=":::::" | |
| else | |
| if [ -z "${FDATA}" ]; then | |
| FDATA=`eval ${SCMD} "\"${FNAME}\"" 2>/dev/null | tr ' ' ':' | sed -e 's/:$//'` | |
| if [ -z "${FDATA}" ]; then | |
| FDATA=":::::" | |
| elif [ -n "`echo ${FDATA} | grep '^[^:]*:0[0-9][0-9][0-9][0-9]:'`" ]; then | |
| # Ensure the file permissions consist of only 4 digits. | |
| FDATA=`echo $FDATA | sed -e 's/^\([^:]*:\)0\(.*\)$/\1\2/'` | |
| fi | |
| fi | |
| fi | |
| # Check if the symbolic link has any colon characters in it. | |
| SYSLNK_CC=`echo "${SYSLNK}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| echo "File:${COLON_COUNT}:${FNAME}:${SYSHASH}:${FDATA}:${PKGNAME}:${SYSLNK_CC}:${SYSLNK}:" >>"${RKHDAT_TMPFILE}" | |
| IFS=$IFSNL | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Display the number of files found in the directories. | |
| # | |
| for DIR in ${DIR_FILE_COUNT}; do | |
| test -z "${DIR}" && continue | |
| RKHTMPVAR=`echo $DIR | cut -d: -f1` | |
| RKHTMPVAR2=`echo $DIR | cut -d: -f2` | |
| display --to LOG --type INFO SET_FILE_PROP_DIR_FILE_COUNT $RKHTMPVAR2 "${RKHTMPVAR}" | |
| done | |
| # | |
| # Finally put the new file in place. | |
| # | |
| if [ -f "${RKHDAT_FILE}" ]; then | |
| RKHTMPVAR="updated" | |
| else | |
| RKHTMPVAR="created" | |
| fi | |
| test $NOHASH_COUNT -gt 0 -o $BROKEN_LINK_COUNT -gt 0 && RET_CODE=1 | |
| # Don't display messages if this is an automatic update. | |
| if [ $OS_CHANGED -eq 1 -a $UPDT_ON_OS_CHANGE -eq 1 ]; then | |
| : | |
| else | |
| if [ $NOHASH_COUNT -eq 0 ]; then | |
| if [ $BROKEN_LINK_COUNT -eq 0 ]; then | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_PROPOPT "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_PROPOPT_COUNT $PROP_FILE_LIST_COUNT | |
| else | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT | |
| fi | |
| else | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_PROPOPT_BL "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_PROPOPT_COUNT $PROP_FILE_LIST_COUNT $BROKEN_LINK_COUNT | |
| else | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_BL "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT $BROKEN_LINK_COUNT | |
| fi | |
| fi | |
| else | |
| if [ $BROKEN_LINK_COUNT -eq 0 ]; then | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_NOHASH_PROPOPT "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_PROPOPT_COUNT $PROP_FILE_LIST_COUNT $NOHASH_COUNT | |
| else | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_NOHASH "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT $NOHASH_COUNT | |
| fi | |
| else | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_NOHASH_PROPOPT_BL "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_PROPOPT_COUNT $PROP_FILE_LIST_COUNT $NOHASH_COUNT $BROKEN_LINK_COUNT | |
| else | |
| display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_NOHASH_BL "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT $NOHASH_COUNT $BROKEN_LINK_COUNT | |
| fi | |
| fi | |
| fi | |
| fi | |
| return | |
| } | |
| create_rkh_file_prop_list() { | |
| # | |
| # This function creates the file of pathnames | |
| # used for the file properties check. | |
| # | |
| get_temp_file "${RKHTMPDIR}/rkh_prop_list.new" | |
| touch "${TEMPFILE}" | |
| IFS=$IFSNL | |
| for DIR in ${PROP_DIR_LIST}; do | |
| for FNAME in ${PROP_FILE_LIST}; do | |
| echo "${DIR}/${FNAME}" >>"${TEMPFILE}" | |
| done | |
| done | |
| # | |
| # Now we add any user specified absolute | |
| # pathnames to be included in the list. | |
| # | |
| if [ -n "${USER_FILE_LIST}" ]; then | |
| for FNAME in ${USER_FILE_LIST}; do | |
| # | |
| # We must exclude any user requested files or directories. | |
| # | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "${USER_EXCLUDE_PROP}" ]; then | |
| test -n "`echo \"${USER_EXCLUDE_PROP}\" | grep \"^${FNAMEGREP}$\"`" && continue | |
| fi | |
| test -z "`grep \"^${FNAMEGREP}$\" "${TEMPFILE}" 2>/dev/null`" && echo "${FNAME}" >>"${TEMPFILE}" | |
| done | |
| fi | |
| IFS=$RKHIFS | |
| cp -f "${TEMPFILE}" "${RKH_FILEPROP_LIST}" >/dev/null 2>&1 | |
| chmod 600 "${RKH_FILEPROP_LIST}" >/dev/null 2>&1 | |
| rm -f "${TEMPFILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| get_old_prop_attrs() { | |
| # | |
| # This function simply determines some of the attributes | |
| # used when the file properties database was created. | |
| # | |
| FNAME=$1 | |
| test -z "${FNAME}" -o ! -f "${FNAME}" && return | |
| if [ -s "${FNAME}" ]; then | |
| OLD_HASH_FUNC=`grep '^Hash:' "${FNAME}" | cut -d: -f2-` | |
| OLD_PKGMGR=`grep '^Pkgmgr:' "${FNAME}" | cut -d: -f2` | |
| OLD_ATTRUPD=`grep '^Attributes:' "${FNAME}" | cut -d: -f2` | |
| fi | |
| return | |
| } | |
| do_prop_update() { | |
| # | |
| # This function updates the local hosts rkhunter.dat file | |
| # with O/S information and file properties. | |
| # | |
| display --to LOG --type INFO --nl PROPUPD_START | |
| # | |
| # First we need to get a temporary file name to use. | |
| # | |
| get_temp_file "${RKHTMPDIR}/rkhunter.dat" | |
| RKHDAT_TMPFILE="${TEMPFILE}" | |
| touch "${RKHDAT_TMPFILE}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${RKHDAT_TMPFILE}" | |
| # | |
| # We now start to write out information about this system | |
| # to the file. Some information we already have available, | |
| # but for others we call functions to obtain what is wanted. | |
| # | |
| rkh_dat_set_version | |
| display --to LOG --type PLAIN PROPUPD_OSINFO_START | |
| rkh_dat_get_os_info | |
| echo "Host:${HOST_NAME}" >>"${RKHDAT_TMPFILE}" | |
| if [ -n "${ARCH}" ]; then | |
| echo "Arch:${ARCH}" >>"${RKHDAT_TMPFILE}" | |
| display --to LOG --type INFO PROPUPD_ARCH_FOUND "${ARCH}" | |
| fi | |
| if [ -n "${RELEASE}" ]; then | |
| display --to LOG --type INFO PROPUPD_REL_FILE "${RELEASE}" | |
| else | |
| RKHTMPVAR=`ls -ld /etc/*release* /etc/*version* 2>/dev/null | tr '\n' ' '` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| display --to LOG --type INFO PROPUPD_NO_REL_FILE | |
| display --to LOG --type PLAIN NAME " ${RKHTMPVAR}" | |
| else | |
| display --to LOG --type INFO PROPUPD_NO_REL_FILE_NO_OUTPUT | |
| fi | |
| fi | |
| if [ -n "${OSNAME}" ]; then | |
| echo "OS:${OSNAME}" >>"${RKHDAT_TMPFILE}" | |
| display --to LOG --type INFO PROPUPD_OSNAME_FOUND "${OSNAME}" | |
| fi | |
| if [ $PRELINKED -eq 0 ]; then | |
| echo "Prelinked:No" >>"${RKHDAT_TMPFILE}" | |
| else | |
| echo "Prelinked:Yes" >>"${RKHDAT_TMPFILE}" | |
| fi | |
| # | |
| # We do not want to bother storing the file hashes or other attibutes | |
| # if the user has disabled these tests permanently. However, to do | |
| # this we must check whether the relevant test is enabled or not, and | |
| # that the --enable/--disable command-line options have not been used. | |
| # | |
| if ! `check_test hashes` && test $ENDIS_OPT -eq 0; then | |
| echo "Hash:Disabled" >>"${RKHDAT_TMPFILE}" | |
| elif [ -n "${PRELINK_HASH}" ]; then | |
| echo "Hash:${PRELINK_HASH}" >>"${RKHDAT_TMPFILE}" | |
| else | |
| echo "Hash:${HASH_FUNC}" >>"${RKHDAT_TMPFILE}" | |
| fi | |
| echo "Pkgmgr:${PKGMGR}" >>"${RKHDAT_TMPFILE}" | |
| if ! `check_test attributes` && test $ENDIS_OPT -eq 0; then | |
| echo "Attributes:Disabled" >>"${RKHDAT_TMPFILE}" | |
| elif [ -z "${STAT_CMD}" ]; then | |
| echo "Attributes:Nostatcmd" >>"${RKHDAT_TMPFILE}" | |
| else | |
| echo "Attributes:Stored" >>"${RKHDAT_TMPFILE}" | |
| fi | |
| echo "FormatVersion:1" >>"${RKHDAT_TMPFILE}" | |
| # | |
| # Before we get the actual file properties we need | |
| # to write out the current list of pathnames. | |
| # | |
| create_rkh_file_prop_list | |
| # | |
| # Next get the file properties. | |
| # | |
| rkh_dat_set_file_properties | |
| # | |
| # We now need to record the hash function and | |
| # package manager as if they were the old values. | |
| # | |
| get_old_prop_attrs "${RKHDAT_TMPFILE}" | |
| # | |
| # Now put the new rkhunter.dat file in place. | |
| # | |
| cp -f -p "${RKHDAT_FILE}" "${RKHDAT_FILE}.old" >/dev/null 2>&1 | |
| cp -f "${RKHDAT_TMPFILE}" "${RKHDAT_FILE}" >/dev/null 2>&1 | |
| ERRCODE=$? | |
| if [ $ERRCODE -ne 0 ]; then | |
| RET_CODE=1 | |
| display --to LOG --type INFO CMD_ERROR "cp ${RKHDAT_TMPFILE} ${RKHDAT_FILE}" $ERRCODE | |
| display --to SCREEN+LOG --type WARNING PROPUPD_ERROR $ERRCODE | |
| else | |
| display --to LOG --type INFO PROPUPD_NEW_DAT_FILE "${DB_PATH}" | |
| fi | |
| chmod 600 "${RKHDAT_FILE}" >/dev/null 2>&1 | |
| rm -f "${RKHDAT_TMPFILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| get_next_mirror() { | |
| # | |
| # This function will obtain the next mirror in the mirrors file | |
| # if no mirror is currently being used. It then optionally | |
| # rotates the mirrors in the file. | |
| # | |
| # | |
| # Return if there is no mirrors file. | |
| # | |
| if [ ! -f "${DB_PATH}/mirrors.dat" ]; then | |
| display --to LOG --type INFO MIRRORS_NO_FILE "${DB_PATH}/mirrors.dat" | |
| return | |
| fi | |
| # | |
| # Return if there are no defined mirrors. | |
| # | |
| case $MIRRORS_MODE in | |
| 0) | |
| MIRROR=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| 1) | |
| MIRROR=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| 2) | |
| MIRROR=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}1` | |
| ;; | |
| esac | |
| if [ -z "${MIRROR}" ]; then | |
| display --to LOG --type INFO MIRRORS_NO_MIRRORS "${DB_PATH}/mirrors.dat" | |
| return | |
| fi | |
| # | |
| # If we are not rotating the mirrors, then we need to calculate | |
| # which one to use next in the list. Return when we have done that. | |
| # | |
| if [ $ROTATE_MIRRORS -eq 0 ]; then | |
| N=`expr $TOTAL_MIRRORS - $MIRROR_COUNT` | |
| case $MIRRORS_MODE in | |
| 0) | |
| MIRROR=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| 1) | |
| MIRROR=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| 2) | |
| MIRROR=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | head ${HEAD_OPT}$N | tail ${TAIL_OPT}1 | cut -d= -f2-` | |
| ;; | |
| esac | |
| return | |
| fi | |
| # | |
| # Now get the version number of the mirrors file. If the version | |
| # does not exist or is corrupt, then we reset it to zero. This | |
| # then allows the file to be updated next time the '--update' | |
| # option is used. | |
| # | |
| MIRRORSVERSION=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' "${DB_PATH}/mirrors.dat" 2>/dev/null | tail ${TAIL_OPT}1` | |
| if [ -z "${MIRRORSVERSION}" ]; then | |
| display --to LOG --type INFO MIRRORS_NO_VERSION "${DB_PATH}/mirrors.dat" | |
| MIRRORSVERSION="Version:0000000000" | |
| fi | |
| # | |
| # Next get the remaining mirrors. | |
| # | |
| OTHERMIRRORS=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | grep -v "^${MIRROR}\$"` | |
| # | |
| # We need to get a temporary file name to use. | |
| # | |
| get_temp_file "${RKHTMPDIR}/mirrors.dat" | |
| MIRRORS_FILE="${TEMPFILE}" | |
| touch "${MIRRORS_FILE}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${MIRRORS_FILE}" | |
| # | |
| # Output to the temporary file the mirrors version, the other | |
| # mirrors, and finally the mirror we are about to use. | |
| # | |
| echo "${MIRRORSVERSION}" >"${MIRRORS_FILE}" | |
| for RKHM in ${OTHERMIRRORS}; do | |
| echo "${RKHM}" >>"${MIRRORS_FILE}" | |
| done; | |
| echo "${MIRROR}" >>"${MIRRORS_FILE}" | |
| MIRROR=`echo "${MIRROR}" | cut -d= -f2-` | |
| # | |
| # Move the new file into place, and delete the temporary file. | |
| # | |
| cat "${MIRRORS_FILE}" >"${DB_PATH}/mirrors.dat" | |
| rm -f "${MIRRORS_FILE}" >/dev/null 2>&1 | |
| display --to LOG --type INFO MIRRORS_ROTATED "${DB_PATH}/mirrors.dat" | |
| return | |
| } | |
| download_file() { | |
| # | |
| # This function downloads a specified file. It takes three parameters: | |
| # 1=mirror, 2=url, 3=output file | |
| # | |
| # The URL is just the filename portion. The user will supply the | |
| # full URL, less the filename, to where the files are stored on | |
| # the local or remote server. For the SourceForge mirrors we will | |
| # provide the URL. | |
| # | |
| # The function sets a return code (DNLOADERR). | |
| # | |
| # | |
| # We loop round through the mirrors until the file is downloaded. | |
| # We do this by first seeing how many mirrors are available. Then | |
| # we call a function to get the next mirror, which also rotates | |
| # the mirror file. If a mirror has already been set, then that | |
| # mirror is used. That way, in effect, once we find a good mirror | |
| # then it will be used for all the downloads. | |
| # | |
| MIRROR=$1 | |
| URL=$2 | |
| OUTPUT_FILE=$3 | |
| DNLOADERR=0 | |
| MIRROR_COUNT=0 | |
| TOTAL_MIRRORS=0 | |
| if [ -n "`echo \"${URL}\" | grep '/rkhunter_latest\.dat$'`" ]; then | |
| DOING_VERS_CHK=1 | |
| else | |
| DOING_VERS_CHK=0 | |
| fi | |
| if [ -f "${DB_PATH}/mirrors.dat" ]; then | |
| # | |
| # The version check will use both the | |
| # SF mirrors and remote mirrors. | |
| # | |
| case $MIRRORS_MODE in | |
| 0) | |
| MIRROR_COUNT=`grep -E -i '^(local|remote|mirror)=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| 1) | |
| MIRROR_COUNT=`grep -E -i '^local=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| 2) | |
| MIRROR_COUNT=`grep -E -i '^remote=https?://[-A-Za-z0-9+@#/%=_:,.]*[-A-Za-z0-9+@#/%=_]$' "${DB_PATH}/mirrors.dat" | wc -l | tr -d ' '` | |
| ;; | |
| esac | |
| test -z "${MIRROR_COUNT}" && MIRROR_COUNT=0 | |
| fi | |
| test $MIRROR_COUNT -eq 0 && MIRROR_COUNT=1 | |
| TOTAL_MIRRORS=$MIRROR_COUNT | |
| while test $MIRROR_COUNT -gt 0; do | |
| MIRROR_COUNT=`expr $MIRROR_COUNT - 1` | |
| if [ -z "${MIRROR}" ]; then | |
| get_next_mirror | |
| if [ -z "${MIRROR}" ]; then | |
| if [ $MIRRORS_MODE -eq 0 ]; then | |
| MIRROR="http://rkhunter.sourceforge.net" | |
| display --to LOG --type INFO MIRRORS_SF_DEFAULT "${MIRROR}" | |
| else | |
| DNLOADERR=1 | |
| break | |
| fi | |
| fi | |
| # | |
| # For the SF mirrors add on the final part of the | |
| # mirror URL, unless we are doing a version check. | |
| # | |
| if [ $DOING_VERS_CHK -eq 0 -a "${MIRROR}" = "http://rkhunter.sourceforge.net" ]; then | |
| MIRROR="${MIRROR}/${RKH_VER_MAJ}.${RKH_VER_MIN}" | |
| fi | |
| fi | |
| # | |
| # Now we can download the data into the temporary file. | |
| # | |
| # uns - WGET_CMD (cmd, version tested, comments): | |
| # wget, *, none. | |
| # bget, 1.2, appends output. | |
| # curl, 7.15.3: none. | |
| # links/elinks, 0.4.2, decompresses output. | |
| # lynx, 2.8.5dev.7, decompresses output. | |
| CMD="" | |
| DNLOADERR=0 | |
| rm -f "${OUTPUT_FILE}" >/dev/null 2>&1 | |
| case "${RKHWEBCMD_BASE}" in | |
| wget) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} -q -O \"${OUTPUT_FILE}\" ${MIRROR}${URL} 2>/dev/null" | |
| ;; | |
| curl) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} --fail --output \"${OUTPUT_FILE}\" ${MIRROR}${URL} 2>/dev/null" | |
| ;; | |
| bget) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} --out \"${OUTPUT_FILE}\" ${MIRROR}${URL} 2>/dev/null" | |
| ;; | |
| links|elinks) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} -no-home 1 -source ${MIRROR}${URL} >\"${OUTPUT_FILE}\" 2>/dev/null" | |
| ;; | |
| lynx) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} -source ${MIRROR}${URL} >\"${OUTPUT_FILE}\" 2>/dev/null" | |
| ;; | |
| GET) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} ${MIRROR}${URL} >\"${OUTPUT_FILE}\" 2>/dev/null" | |
| ;; | |
| *) | |
| CMD="${RKHWEBCMD} ${RKHWEBCMD_OPTS} ${MIRROR}${URL} >\"${OUTPUT_FILE}\" 2>/dev/null" | |
| ;; | |
| esac | |
| display --to LOG --type INFO DOWNLOAD_CMD "${CMD}" | |
| eval ${CMD} | |
| DNLOADERR=$? | |
| test $DNLOADERR -gt 1 && DNLOADERR=1 | |
| # | |
| # Some of these commands do not set the return code. As such we | |
| # need to look in the output file to see if an error occurred. | |
| # | |
| if [ $DNLOADERR -eq 0 ]; then | |
| if [ -n "`echo \"${URL}\" | grep '/i18n\.ver$'`" ]; then | |
| # | |
| # The i18n.ver file is of a different | |
| # format from the other files. | |
| # | |
| : | |
| elif [ $DOING_VERS_CHK -eq 1 ]; then | |
| # | |
| # The versioncheck file should just be a version number. | |
| # | |
| if [ -z "`grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' \"${OUTPUT_FILE}\"`" ]; then | |
| DNLOADERR=1 | |
| fi | |
| else | |
| # | |
| # All other files should have a normal | |
| # version number as the first line in them. | |
| # | |
| if [ -z "`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' \"${OUTPUT_FILE}\"`" ]; then | |
| DNLOADERR=1 | |
| fi | |
| fi | |
| fi | |
| test ! -s "${OUTPUT_FILE}" && DNLOADERR=1 | |
| if [ $DNLOADERR -eq 0 ]; then | |
| break | |
| elif [ $MIRROR_COUNT -gt 0 ]; then | |
| MIRROR="" | |
| display --to LOG --type INFO DOWNLOAD_FAIL $MIRROR_COUNT | |
| fi | |
| done | |
| return $DNLOADERR | |
| } | |
| do_i18n_update() { | |
| # | |
| # This function updates the i18n language files. | |
| # | |
| # We do not know which i18n files should be checked until we | |
| # have downloaded the i18n/i18n.ver file. This file will tell | |
| # us which i18n files are available, and their latest version | |
| # number. We loop through the files, and check each version | |
| # number against the installed file. | |
| # | |
| download_file "${MIRROR}" "/i18n/${PROGRAM_version}/i18n.ver" "${RKHUPD_FILE}" | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Check that we have some version numbers. There | |
| # should always be at least one, for the English | |
| # language! Once we have the list of files, we can | |
| # remove the temporary file and re-use it when | |
| # downloading the language files. | |
| # | |
| FOUNDFILES=`grep '^[a-zA-Z][a-zA-Z0-9._-]*:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' "${RKHUPD_FILE}"` | |
| rm -f "${RKHUPD_FILE}" >/dev/null 2>&1 | |
| if [ -z "${FOUNDFILES}" ]; then | |
| RET_CODE=1 | |
| UPD_ERROR=1 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE 'i18n versions' | |
| display --to LOG --type WARNING UPDATE_I18N_NO_VERS | |
| return | |
| fi | |
| # | |
| # Now loop through the language files checking their | |
| # version numbers. | |
| # | |
| for FNAME in ${FOUNDFILES}; do | |
| LANGFILE=`echo "${FNAME}" | cut -d: -f1` | |
| LATEST_VERS=`echo "${FNAME}" | cut -d: -f2` | |
| # | |
| # Only update the language files the user has asked for. | |
| # | |
| if [ -n "${UPDATE_LANG}" ]; then | |
| if [ -z "`echo \" ${UPDATE_LANG} \" | grep \" ${LANGFILE} \"`" ]; then | |
| display --to LOG --type INFO UPDATE_SKIPPED | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color YELLOW --result SKIPPED UPDATE_CHECKING_FILE "i18n/${LANGFILE}" | |
| continue | |
| fi | |
| fi | |
| if [ -s "${DB_PATH}/i18n/${LANGFILE}" ]; then | |
| PROG_VERS=`grep ${GREP_OPT} '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' "${DB_PATH}/i18n/${LANGFILE}" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f2` | |
| if [ -z "${PROG_VERS}" ]; then | |
| PROG_VERS=0 | |
| display --to LOG --type INFO UPDATE_FILE_NO_VERS "${DB_PATH}/i18n/${LANGFILE}" | |
| fi | |
| else | |
| PROG_VERS=0 | |
| touch "${DB_PATH}/i18n/${LANGFILE}" >/dev/null 2>&1 | |
| chmod 600 "${DB_PATH}/i18n/${LANGFILE}" >/dev/null 2>&1 | |
| display --to LOG --type INFO UPDATE_FILE_MISSING "${DB_PATH}/i18n/${LANGFILE}" | |
| fi | |
| display --to LOG --type INFO VERSIONCHECK_CURRENT "${PROG_VERS}" | |
| display --to LOG --type INFO VERSIONCHECK_LATEST "${LATEST_VERS}" | |
| if [ $PROG_VERS -lt $LATEST_VERS ]; then | |
| download_file "${MIRROR}" "/i18n/${PROGRAM_version}/${LANGFILE}" "${RKHUPD_FILE}" | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| test $RET_CODE -eq 0 && RET_CODE=2 | |
| cat "${RKHUPD_FILE}" >"${DB_PATH}/i18n/${LANGFILE}" | |
| display --to LOG --type INFO VERSIONCHECK_UPDT_AVAIL | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result UPD UPDATE_CHECKING_FILE "i18n/${LANGFILE}" | |
| else | |
| RET_CODE=1 | |
| UPD_ERROR=1 | |
| display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL "i18n/${LANGFILE}" | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "i18n/${LANGFILE}" | |
| fi | |
| rm -f "${RKHUPD_FILE}" >/dev/null 2>&1 | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result NO_UPD UPDATE_CHECKING_FILE "i18n/${LANGFILE}" | |
| fi | |
| done | |
| else | |
| RET_CODE=1 | |
| UPD_ERROR=1 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE 'i18n versions' | |
| display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL 'i18n.ver' | |
| fi | |
| rm -f "${RKHUPD_FILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| do_update() { | |
| # | |
| # This function checks to see if any of the supplied RKH | |
| # *.dat and i18n files needs updating. If it does, then the | |
| # file is overwritten with the new version. | |
| # | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --nl UPDATE_START | |
| # | |
| # First we need to get a temporary file name to use. | |
| # | |
| get_temp_file "${RKHTMPDIR}/rkhunter.upd" | |
| RKHUPD_FILE="${TEMPFILE}" | |
| touch "${RKHUPD_FILE}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${RKHUPD_FILE}" | |
| # | |
| # Now we loop round through the files we need to check. Each file | |
| # will use the first mirror, and if necessary loop through the | |
| # remaining mirrors until the file is downloaded. In theory this | |
| # could take some time if the mirror sites are all experiencing | |
| # problems and this is affecting all the files. | |
| # | |
| # For each file we look at the current version number. If there | |
| # is a problem doing this, then we just try and download a new | |
| # copy of the file. If the version number is okay, then we | |
| # download the file to find the latest version number. If | |
| # that is successful, we then update the file if necessary. | |
| # | |
| UPD_ERROR=0 | |
| MIRROR="" | |
| for UPDFILE in mirrors.dat programs_bad.dat backdoorports.dat suspscan.dat; do | |
| if [ $UPDATE_MIRRORS -eq 0 -a "${UPDFILE}" = "mirrors.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result SKIPPED UPDATE_CHECKING_FILE "${UPDFILE}" | |
| continue | |
| fi | |
| LATEST_VERS=0 | |
| if [ -s "${DB_PATH}/${UPDFILE}" ]; then | |
| PROG_VERS=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' "${DB_PATH}/${UPDFILE}" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f2` | |
| if [ -z "${PROG_VERS}" ]; then | |
| PROG_VERS=0 | |
| display --to LOG --type INFO UPDATE_FILE_NO_VERS "${UPDFILE}" | |
| fi | |
| else | |
| PROG_VERS=0 | |
| touch "${DB_PATH}/${UPDFILE}" >/dev/null 2>&1 | |
| chmod 600 "${DB_PATH}/${UPDFILE}" >/dev/null 2>&1 | |
| display --to LOG --type INFO UPDATE_FILE_MISSING "${UPDFILE}" | |
| fi | |
| # | |
| # Now download the file. | |
| # | |
| # Note: To avoid any backward incompatability we | |
| # get the files from a specific directory which | |
| # previous versions do not use. | |
| # | |
| download_file "${MIRROR}" "/${UPDFILE}" "${RKHUPD_FILE}" | |
| ERRCODE=$? | |
| # | |
| # Next we compare the current and downloaded | |
| # file version numbers. | |
| # | |
| if [ $ERRCODE -eq 0 ]; then | |
| LATEST_VERS=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' "${RKHUPD_FILE}" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f2` | |
| if [ -z "${LATEST_VERS}" ]; then | |
| LATEST_VERS=0 | |
| elif [ -z "`echo \"${LATEST_VERS}\" | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$'`" ]; then | |
| LATEST_VERS=0 | |
| fi | |
| display --to LOG --type INFO VERSIONCHECK_CURRENT "${PROG_VERS}" | |
| display --to LOG --type INFO VERSIONCHECK_LATEST "${LATEST_VERS}" | |
| if [ $LATEST_VERS -eq 0 ]; then | |
| RET_CODE=1 | |
| UPD_ERROR=1 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result VCHK_FAILED UPDATE_CHECKING_FILE "${UPDFILE}" | |
| LATEST_VERS=`head ${HEAD_OPT}1 ${RKHUPD_FILE}` | |
| display --to LOG --type WARNING VERSIONCHECK_CONV_FAIL "${PROG_VERS}" "${LATEST_VERS}" | |
| elif [ $PROG_VERS -lt $LATEST_VERS ]; then | |
| test $RET_CODE -eq 0 && RET_CODE=2 | |
| display --to LOG --type INFO VERSIONCHECK_UPDT_AVAIL | |
| cat "${RKHUPD_FILE}" >"${DB_PATH}/${UPDFILE}" | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result UPD UPDATE_CHECKING_FILE "${UPDFILE}" | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result NO_UPD UPDATE_CHECKING_FILE "${UPDFILE}" | |
| fi | |
| else | |
| RET_CODE=1 | |
| UPD_ERROR=1 | |
| display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL "${UPDFILE}" | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "${UPDFILE}" | |
| fi | |
| rm -f "${RKHUPD_FILE}" >/dev/null 2>&1 | |
| done | |
| # | |
| # We now need to update the i18n files. Since this is a little | |
| # more complicated, it is handled in a separate function. | |
| # | |
| do_i18n_update | |
| if [ $UPD_ERROR -eq 1 ]; then | |
| if [ $NOLOG -eq 1 ]; then | |
| display --to SCREEN --type PLAIN --nl --nl-after CHECK_WARNINGS_FOUND_RERUN | |
| else | |
| display --to SCREEN --type PLAIN --nl --nl-after CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}" | |
| fi | |
| fi | |
| return | |
| } | |
| do_versioncheck() { | |
| # | |
| # This function performs a program version check. | |
| # | |
| # It will set the return code in some instances: | |
| # 0 - (implied) no error, no new version available | |
| # 1 - a download (of the version number) error occurred | |
| # 2 - no error occurred, but a new version is available | |
| # | |
| MIRROR="" | |
| LATESTVERSION="" | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --nl VERSIONCHECK_START | |
| # | |
| # First we need to get a temporary file name to use. | |
| # | |
| get_temp_file "${RKHTMPDIR}/rkhunter.vc" | |
| RKHVC_FILE="${TEMPFILE}" | |
| touch "${RKHVC_FILE}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${RKHVC_FILE}" | |
| # | |
| # Next we get the current program version number. | |
| # | |
| PROG_VERS=`echo "${PROGRAM_version}" | cut -d. -f1-3 | sed -e 's/\.\([0-9]\)\./.0\1./' | sed -e 's/\.\([0-9]\)$/.0\1/' | tr -d '.'` | |
| test -z "${PROG_VERS}" && PROG_VERS=0 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_CURRENT "${PROGRAM_version}" | |
| # | |
| # Download the file, and then compare the current value | |
| # with the downloaded one. | |
| # | |
| download_file "${MIRROR}" "/rkhunter_latest.dat" "${RKHVC_FILE}" | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| LATESTVERSION=`cat "${RKHVC_FILE}" 2>/dev/null` | |
| # | |
| # Convert the version string to zero-spaced numbers. | |
| # This allows us to numerically compare the versions, | |
| # even when the numbers go above ten. | |
| # | |
| # E.g. '1.2.10' => 10210, '1.3.2' => 10302. | |
| # | |
| LATEST_VERS=`echo "${LATESTVERSION}" | cut -d. -f1-3 | sed -e 's/\.\([0-9]\)\./.0\1./' | sed -e 's/\.\([0-9]\)$/.0\1/' | tr -d '.'` | |
| test -z "${LATEST_VERS}" && LATEST_VERS=0 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_LATEST "${LATESTVERSION}" | |
| if [ $LATEST_VERS -eq 0 ]; then | |
| RET_CODE=1 | |
| display --to SCREEN+LOG --type WARNING --screen-indent 2 VERSIONCHECK_CONV_FAIL "${PROGRAM_version}" "${LATESTVERSION}" | |
| elif [ $PROG_VERS -lt $LATEST_VERS ]; then | |
| test $RET_CODE -eq 0 && RET_CODE=2 | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_UPDT_AVAIL | |
| fi | |
| else | |
| RET_CODE=1 | |
| display --to LOG --type WARNING VERSIONCHECK_FAIL_ALL | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_LATEST_FAIL | |
| fi | |
| rm -f "${RKHVC_FILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| do_config_file_check() { | |
| # | |
| # This function performs a basic configuration file check. Use of | |
| # the configuration check command-line option will cause the known | |
| # configured options to be checked as usual. So all we need to do | |
| # here is look for any configuration options which are unknown. | |
| # | |
| # | |
| # First we define the list of valid configuration options. | |
| # | |
| # | |
| # All the following specified options should be single | |
| # value options (that is, not any sort of list). | |
| # | |
| VALIDOPTS="${SPACE_LIST_OPTS} ${NEWLINE_LIST_OPTS} | |
| ALLOW_SSH_PROT_V1 ALLOW_SSH_ROOT_USER ALLOW_SYSLOG_REMOTE_LOGGING APPEND_LOG | |
| AUTO_X_DETECT COLOR_SET2 COPY_LOG_ON_ERROR DBDIR EPOCH_DATE_CMD GLOBSTAR | |
| HASH_FLD_IDX HASH_FUNC HASH_CMD IMMUTABLE_SET INETD_CONF_PATH INSTALLDIR | |
| IPC_SEG_SIZE LANGUAGE LOCKDIR LOCK_TIMEOUT LOGFILE MAIL_CMD MIRRORS_MODE MODULES_DIR | |
| OS_VERSION_FILE PASSWORD_FILE PHALANX2_DIRTEST PKGMGR ROOTDIR ROTATE_MIRRORS | |
| SCAN_MODE_DEV SCANROOTKITMODE SCRIPTDIR SHOW_LOCK_MSGS SHOW_SUMMARY_TIME SHOW_SUMMARY_WARNINGS_NUMBER | |
| SKIP_INODE_CHECK SSH_CONFIG_DIR SUSPSCAN_DEBUG SUSPSCAN_LINETHRESH SUSPSCAN_MAXSIZE SUSPSCAN_TEMP | |
| SUSPSCAN_THRESH TMPDIR UPDATE_MIRRORS UPDT_ON_OS_CHANGE USE_SUNSUM USE_LOCKING | |
| USE_SYSLOG WARN_ON_OS_CHANGE WEBCMD WEB_CMD WHITELISTED_IS_WHITE | |
| XINETD_CONF_PATH" | |
| VALIDOPTS=" `echo ${VALIDOPTS}` " | |
| # | |
| # Now check to see if any unknown options have been configured. | |
| # | |
| RKHTMPVAR=`grep -E -h -v '^[ ]*(#|$)' ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES}` | |
| IFS=$IFSNL | |
| for CONFIGOPT in ${RKHTMPVAR}; do | |
| CONFIGCMD=`echo ${CONFIGOPT} | cut -d= -f1` | |
| # | |
| # We have to handle the *_CMD entries specially because | |
| # only certain commands are allowed to be replaced by | |
| # a configuration option. | |
| # | |
| if [ -n "`echo ${CONFIGCMD} | grep '_CMD$'`" ]; then | |
| case "${CONFIGCMD}" in | |
| EPOCH_DATE_CMD|MAIL_CMD|WEB_CMD|HASH_CMD) | |
| # We know about these ones. | |
| ;; | |
| *) | |
| # Dig out the actual command name used. | |
| CFG_CMD=`echo ${CONFIGCMD} | sed -e 's/_CMD$//'` | |
| # Check to see if the command is one we now about. | |
| if [ -z "`echo \" ${CMDLIST} \" | grep -i \" ${CFG_CMD} \"`" ]; then | |
| RET_CODE=1 | |
| echo "Unknown configuration file option: ${CONFIGOPT}" | |
| fi | |
| ;; | |
| esac | |
| continue | |
| fi | |
| if [ -z "`echo \"${VALIDOPTS}\" | grep \" ${CONFIGCMD} \"`" ]; then | |
| RET_CODE=1 | |
| echo "Unknown configuration file option: ${CONFIGOPT}" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| return | |
| } | |
| do_system_check_initialisation() { | |
| # | |
| # This function simply initialises the default rootkit | |
| # files and directories. | |
| # | |
| # 55808 Variant A | |
| W55808A_FILES="/tmp/.../r | |
| /tmp/.../a" | |
| W55808A_DIRS= | |
| W55808A_KSYMS= | |
| # Adore Rootkit. OK, nobody calls it that but basically it uses Adore. | |
| # In one commercial AV vendors naming scheme it's called Dextenea. | |
| AKIT_FILES="/usr/secure | |
| /usr/doc/sys/qrt | |
| /usr/doc/sys/run | |
| /usr/doc/sys/crond | |
| /usr/sbin/kfd | |
| /usr/doc/kern/var | |
| /usr/doc/kern/string.o | |
| /usr/doc/kern/ava | |
| /usr/doc/kern/adore.o | |
| /var/log/ssh/old" | |
| AKIT_DIRS="/lib/security/.config/ssh | |
| /usr/doc/kern | |
| /usr/doc/backup | |
| /usr/doc/backup/txt | |
| /lib/backup | |
| /lib/backup/txt | |
| /usr/doc/work | |
| /usr/doc/sys | |
| /var/log/ssh | |
| /usr/doc/.spool | |
| /usr/lib/kterm" | |
| AKIT_KSYMS= | |
| # AjaKit Rootkit | |
| AJAKIT_FILES="/dev/tux/.addr | |
| /dev/tux/.proc | |
| /dev/tux/.file | |
| /lib/.libgh-gh/cleaner | |
| /lib/.libgh-gh/Patch/patch | |
| /lib/.libgh-gh/sb0k" | |
| AJAKIT_DIRS="/dev/tux | |
| /lib/.libgh-gh" | |
| AJAKIT_KSYMS= | |
| # aPa Kit Rootkit | |
| APAKIT_FILES="/usr/share/.aPa" | |
| APAKIT_DIRS= | |
| APAKIT_KSYMS= | |
| # Apache Worm | |
| APACHEWORM_FILES="/bin/.log" | |
| APACHEWORM_DIRS= | |
| APACHEWORM_KSYMS= | |
| # Ambient (ark) Rootkit | |
| ARK_FILES="/usr/lib/.ark? | |
| /dev/ptyxx/.log | |
| /dev/ptyxx/.file | |
| /dev/ptyxx/.proc | |
| /dev/ptyxx/.addr" | |
| ARK_DIRS="/dev/ptyxx" | |
| ARK_KSYMS= | |
| # Balaur Rootkit 2.0 (LRK5 based) | |
| BALAUR_FILES="/usr/lib/liblog.o" | |
| BALAUR_DIRS="/usr/lib/.kinetic | |
| /usr/lib/.egcs | |
| /usr/lib/.wormie" | |
| BALAUR_KSYMS= | |
| # Beastkit Rootkit | |
| BEASTKIT_FILES="/usr/sbin/arobia | |
| /usr/sbin/idrun | |
| /usr/lib/elm/arobia/elm | |
| /usr/lib/elm/arobia/elm/hk | |
| /usr/lib/elm/arobia/elm/hk.pub | |
| /usr/lib/elm/arobia/elm/sc | |
| /usr/lib/elm/arobia/elm/sd.pp | |
| /usr/lib/elm/arobia/elm/sdco | |
| /usr/lib/elm/arobia/elm/srsd" | |
| BEASTKIT_DIRS="/lib/ldd.so/bktools" | |
| BEASTKIT_KSYMS= | |
| # beX2 Rootkit | |
| BEX_FILES="/usr/info/termcap.info-5.gz | |
| /usr/bin/sshd2" | |
| BEX_DIRS="/usr/include/bex" | |
| BEX_KSYMS= | |
| # BOBkit Rootkit | |
| BOBKIT_FILES="/usr/sbin/ntpsx | |
| /usr/sbin/.../bkit-ava | |
| /usr/sbin/.../bkit-d | |
| /usr/sbin/.../bkit-shd | |
| /usr/sbin/.../bkit-f | |
| /usr/include/.../proc.h | |
| /usr/include/.../.bash_history | |
| /usr/include/.../bkit-get | |
| /usr/include/.../bkit-dl | |
| /usr/include/.../bkit-screen | |
| /usr/include/.../bkit-sleep | |
| /usr/lib/.../bkit-adore.o | |
| /usr/lib/.../ls | |
| /usr/lib/.../netstat | |
| /usr/lib/.../lsof | |
| /usr/lib/.../bkit-ssh/bkit-shdcfg | |
| /usr/lib/.../bkit-ssh/bkit-shhk | |
| /usr/lib/.../bkit-ssh/bkit-pw | |
| /usr/lib/.../bkit-ssh/bkit-shrs | |
| /usr/lib/.../bkit-ssh/bkit-mots | |
| /usr/lib/.../uconf.inv | |
| /usr/lib/.../psr | |
| /usr/lib/.../find | |
| /usr/lib/.../pstree | |
| /usr/lib/.../slocate | |
| /usr/lib/.../du | |
| /usr/lib/.../top" | |
| BOBKIT_DIRS="/usr/sbin/... | |
| /usr/include/... | |
| /usr/include/.../.tmp | |
| /usr/lib/... | |
| /usr/lib/.../.ssh | |
| /usr/lib/.../bkit-ssh | |
| /usr/lib/.bkit- | |
| /tmp/.bkp" | |
| BOBKIT_KSYMS= | |
| # OSX Boonana-A Trojan (aka Koobface.A) | |
| BOONANA_FILES="/Library/StartupItems/OSXDriverUpdates/OSXDriverUpdates | |
| /Library/StartupItems/OSXDriverUpdates/StartupParameters.plist" | |
| BOONANA_DIRS="/var/root/.jnana" | |
| BOONANA_KSYMS= | |
| # cb Rootkit (w00tkit by ZeeN) | |
| # The '%' character represents a space. | |
| # xC.o = Adore LKM | |
| CB_FILES="/dev/srd0 | |
| /lib/libproc.so.2.0.6 | |
| /dev/mounnt | |
| /etc/rc.d/init.d/init | |
| /usr/bin/.zeen/..%/cl | |
| /usr/bin/.zeen/..%/.x.tgz | |
| /usr/bin/.zeen/..%/statdx | |
| /usr/bin/.zeen/..%/wted | |
| /usr/bin/.zeen/..%/write | |
| /usr/bin/.zeen/..%/scan | |
| /usr/bin/.zeen/..%/sc | |
| /usr/bin/.zeen/..%/sl2 | |
| /usr/bin/.zeen/..%/wroot | |
| /usr/bin/.zeen/..%/wscan | |
| /usr/bin/.zeen/..%/wu | |
| /usr/bin/.zeen/..%/v | |
| /usr/bin/.zeen/..%/read | |
| /usr/lib/sshrc | |
| /usr/lib/ssh_host_key | |
| /usr/lib/ssh_host_key.pub | |
| /usr/lib/ssh_random_seed | |
| /usr/lib/sshd_config | |
| /usr/lib/shosts.equiv | |
| /usr/lib/ssh_known_hosts | |
| /u/zappa/.ssh/pid | |
| /usr/bin/.system/..%/tcp.log | |
| /usr/bin/.zeen/..%/curatare/attrib | |
| /usr/bin/.zeen/..%/curatare/chattr | |
| /usr/bin/.zeen/..%/curatare/ps | |
| /usr/bin/.zeen/..%/curatare/pstree | |
| /usr/bin/.system/..%/.x/xC.o" | |
| CB_DIRS="/usr/bin/.zeen | |
| /usr/bin/.zeen/..%/curatare | |
| /usr/bin/.zeen/..%/scan | |
| /usr/bin/.system/..%" | |
| CB_KSYMS= | |
| # CiNIK Worm (Slapper.B variant) | |
| CINIK_FILES="/tmp/.cinik" | |
| CINIK_DIRS="/tmp/.font-unix/.cinik" | |
| CINIK_KSYMS= | |
| # CX Rootkit | |
| CXKIT_FILES="/usr/lib/ldlibso | |
| /usr/lib/configlibso | |
| /usr/lib/shklibso | |
| /usr/lib/randomlibso | |
| /usr/lib/ldlibstrings.so | |
| /usr/lib/ldlibdu.so | |
| /usr/lib/ldlibns.so | |
| /usr/include/db" | |
| CXKIT_DIRS="/usr/include/cxk" | |
| CXKIT_KSYMS= | |
| # Danny-Boy's Abuse Kit | |
| DANNYBOYS_FILES="/dev/mdev | |
| /usr/lib/libX.a" | |
| DANNYBOYS_DIRS= | |
| DANNYBOYS_KSYMS= | |
| # Devil Rootkit | |
| DEVIL_FILES="/var/lib/games/.src | |
| /dev/dsx | |
| /dev/caca | |
| /dev/pro | |
| /bin/bye | |
| /bin/homedir | |
| /usr/bin/xfss | |
| /usr/sbin/tzava | |
| /usr/doc/tar/.../.dracusor/stuff/holber | |
| /usr/doc/tar/.../.dracusor/stuff/sense | |
| /usr/doc/tar/.../.dracusor/stuff/clear | |
| /usr/doc/tar/.../.dracusor/stuff/tzava | |
| /usr/doc/tar/.../.dracusor/stuff/citeste | |
| /usr/doc/tar/.../.dracusor/stuff/killrk | |
| /usr/doc/tar/.../.dracusor/stuff/searchlog | |
| /usr/doc/tar/.../.dracusor/stuff/gaoaza | |
| /usr/doc/tar/.../.dracusor/stuff/cleaner | |
| /usr/doc/tar/.../.dracusor/stuff/shk | |
| /usr/doc/tar/.../.dracusor/stuff/srs | |
| /usr/doc/tar/.../.dracusor/utile.tgz | |
| /usr/doc/tar/.../.dracusor/webpage | |
| /usr/doc/tar/.../.dracusor/getpsy | |
| /usr/doc/tar/.../.dracusor/getbnc | |
| /usr/doc/tar/.../.dracusor/getemech | |
| /usr/doc/tar/.../.dracusor/localroot.sh | |
| /usr/doc/tar/.../.dracusor/stuff/old/sense" | |
| DEVIL_DIRS="/usr/doc/tar/.../.dracusor" | |
| DEVIL_KSYMS= | |
| # Diamorphine LKM | |
| DIAMORPHINE_FILES= | |
| DIAMORPHINE_DIRS= | |
| DIAMORPHINE_KSYMS="diamorphine | |
| module_hide | |
| module_hidden | |
| is_invisible | |
| hacked_getdents | |
| hacked_kill" | |
| # Dica-Kit (T0rn variant) Rootkit | |
| DICA_FILES="/lib/.sso | |
| /lib/.so | |
| /var/run/...dica/clean | |
| /var/run/...dica/dxr | |
| /var/run/...dica/read | |
| /var/run/...dica/write | |
| /var/run/...dica/lf | |
| /var/run/...dica/xl | |
| /var/run/...dica/xdr | |
| /var/run/...dica/psg | |
| /var/run/...dica/secure | |
| /var/run/...dica/rdx | |
| /var/run/...dica/va | |
| /var/run/...dica/cl.sh | |
| /var/run/...dica/last.log | |
| /usr/bin/.etc | |
| /etc/sshd_config | |
| /etc/ssh_host_key | |
| /etc/ssh_random_seed" | |
| DICA_DIRS="/var/run/...dica | |
| /var/run/...dica/mh | |
| /var/run/...dica/scan" | |
| DICA_KSYMS= | |
| # Dreams Rootkit | |
| DREAMS_FILES="/dev/ttyoa | |
| /dev/ttyof | |
| /dev/ttyop | |
| /usr/bin/sense | |
| /usr/bin/sl2 | |
| /usr/bin/logclear | |
| /usr/bin/(swapd) | |
| /usr/bin/initrd | |
| /usr/bin/crontabs | |
| /usr/bin/snfs | |
| /usr/lib/libsss | |
| /usr/lib/libsnf.log | |
| /usr/lib/libshtift/top | |
| /usr/lib/libshtift/ps | |
| /usr/lib/libshtift/netstat | |
| /usr/lib/libshtift/ls | |
| /usr/lib/libshtift/ifconfig | |
| /usr/include/linseed.h | |
| /usr/include/linpid.h | |
| /usr/include/linkey.h | |
| /usr/include/linconf.h | |
| /usr/include/iceseed.h | |
| /usr/include/icepid.h | |
| /usr/include/icekey.h | |
| /usr/include/iceconf.h" | |
| DREAMS_DIRS="/dev/ida/.hpd | |
| /usr/lib/libshtift" | |
| DREAMS_KSYMS= | |
| # Duarawkz Rootkit | |
| DUARAWKZ_FILES="/usr/bin/duarawkz/loginpass" | |
| DUARAWKZ_DIRS="/usr/bin/duarawkz" | |
| DUARAWKZ_KSYMS= | |
| # Ebury sshd backdoor | |
| EBURY_FILES="/lib/libns2.so | |
| /lib64/libns2.so | |
| /lib/libns5.so | |
| /lib64/libns5.so | |
| /lib/libpw3.so | |
| /lib64/libpw3.so | |
| /lib/libpw5.so | |
| /lib64/libpw5.so | |
| /lib/libsbr.so | |
| /lib64/libsbr.so | |
| /lib/libslr.so | |
| /lib64/libslr.so | |
| /lib/tls/libkeyutils.so.1 | |
| /lib64/tls/libkeyutils.so.1" | |
| EBURY_DIRS= | |
| EBURY_KSYMS= | |
| # ENYE LKM v1.1, v1.2 | |
| # Installer default. | |
| ENYELKM_FILES="/etc/.enyelkmHIDE^IT.ko | |
| /etc/.enyelkmOCULTAR.ko" | |
| ENYELKM_DIRS= | |
| ENYELKM_KSYMS= | |
| # Flea Linux Rootkit | |
| FLEA_FILES="/etc/ld.so.hash | |
| /lib/security/.config/ssh/sshd_config | |
| /lib/security/.config/ssh/ssh_host_key | |
| /lib/security/.config/ssh/ssh_host_key.pub | |
| /lib/security/.config/ssh/ssh_random_seed | |
| /usr/bin/ssh2d | |
| /usr/lib/ldlibns.so | |
| /usr/lib/ldlibps.so | |
| /usr/lib/ldlibpst.so | |
| /usr/lib/ldlibdu.so | |
| /usr/lib/ldlibct.so" | |
| FLEA_DIRS="/lib/security/.config/ssh | |
| /dev/..0 | |
| /dev/..0/backup" | |
| FLEA_KSYMS= | |
| # FreeBSD Rootkit (FBRK) catering to versions and compile-time defaults used by: | |
| # 1.0 (1997, Method), 1.2 (1997, Method), "ImperialS-FBRK 1.0" (2001, Nyo) | |
| FREEBSD_RK_FILES="/dev/ptyp | |
| /dev/ptyq | |
| /dev/ptyr | |
| /dev/ptys | |
| /dev/ptyt | |
| /dev/fd/.88/freshb-bsd | |
| /dev/fd/.88/fresht | |
| /dev/fd/.88/zxsniff | |
| /dev/fd/.88/zxsniff.log | |
| /dev/fd/.99/.ttyf00 | |
| /dev/fd/.99/.ttyp00 | |
| /dev/fd/.99/.ttyq00 | |
| /dev/fd/.99/.ttys00 | |
| /dev/fd/.99/.pwsx00 | |
| /etc/.acid | |
| /usr/lib/.fx/sched_host.2 | |
| /usr/lib/.fx/random_d.2 | |
| /usr/lib/.fx/set_pid.2 | |
| /usr/lib/.fx/setrgrp.2 | |
| /usr/lib/.fx/TOHIDE | |
| /usr/lib/.fx/cons.saver | |
| /usr/lib/.fx/adore/ava/ava | |
| /usr/lib/.fx/adore/adore/adore.ko | |
| /bin/sysback | |
| /usr/local/bin/sysback" | |
| FREEBSD_RK_DIRS="/dev/fd/.88 | |
| /dev/fd/.99 | |
| /usr/lib/.fx | |
| /usr/lib/.fx/adore" | |
| FREEBSD_RK_KSYMS= | |
| # Fu Rootkit | |
| FU_FILES="/sbin/xc | |
| /usr/include/ivtype.h | |
| /bin/.lib" | |
| FU_DIRS= | |
| FU_KSYMS= | |
| # Fuckit Rootkit | |
| FUCKIT_FILES="/lib/libproc.so.2.0.7 | |
| /dev/proc/.bash_profile | |
| /dev/proc/.bashrc | |
| /dev/proc/.cshrc | |
| /dev/proc/fuckit/hax0r | |
| /dev/proc/fuckit/hax0rshell | |
| /dev/proc/fuckit/config/lports | |
| /dev/proc/fuckit/config/rports | |
| /dev/proc/fuckit/config/rkconf | |
| /dev/proc/fuckit/config/password | |
| /dev/proc/fuckit/config/progs | |
| /dev/proc/fuckit/system-bins/init | |
| /usr/lib/libcps.a | |
| /usr/lib/libtty.a" | |
| FUCKIT_DIRS="/dev/proc | |
| /dev/proc/fuckit | |
| /dev/proc/fuckit/system-bins | |
| /dev/proc/toolz" | |
| FUCKIT_KSYMS= | |
| # GasKit Rootkit | |
| GASKIT_FILES="/dev/dev/gaskit/sshd/sshdd" | |
| GASKIT_DIRS="/dev/dev | |
| /dev/dev/gaskit | |
| /dev/dev/gaskit/sshd" | |
| GASKIT_KSYMS= | |
| # Heroin LKM | |
| HEROIN_FILES= | |
| HEROIN_DIRS= | |
| HEROIN_KSYMS="heroin" | |
| # HjC Kit Rootkit | |
| HJCKIT_FILES= | |
| HJCKIT_DIRS="/dev/.hijackerz" | |
| HJCKIT_KSYMS= | |
| # ignoKit Rootkit | |
| IGNOKIT_FILES="/lib/defs/p | |
| /lib/defs/q | |
| /lib/defs/r | |
| /lib/defs/s | |
| /lib/defs/t | |
| /usr/lib/defs/p | |
| /usr/lib/defs/q | |
| /usr/lib/defs/r | |
| /usr/lib/defs/s | |
| /usr/lib/defs/t | |
| /usr/lib/.libigno/pkunsec | |
| /usr/lib/.libigno/.igno/psybnc/psybnc" | |
| IGNOKIT_DIRS="/usr/lib/.libigno | |
| /usr/lib/.libigno/.igno" | |
| IGNOKIT_KSYMS= | |
| # iLLogiC Rootkit (SunOS Rootkit variant) | |
| ILLOGIC_FILES="/dev/kmod | |
| /dev/dos | |
| /usr/lib/crth.o | |
| /usr/lib/crtz.o | |
| /etc/ld.so.hash | |
| /usr/bin/sia | |
| /usr/bin/ssh2d | |
| /lib/security/.config/sn | |
| /lib/security/.config/iver | |
| /lib/security/.config/uconf.inv | |
| /lib/security/.config/ssh/ssh_host_key | |
| /lib/security/.config/ssh/ssh_host_key.pub | |
| /lib/security/.config/ssh/sshport | |
| /lib/security/.config/ssh/ssh_random_seed | |
| /lib/security/.config/ava | |
| /lib/security/.config/cleaner | |
| /lib/security/.config/lpsched | |
| /lib/security/.config/sz | |
| /lib/security/.config/rcp | |
| /lib/security/.config/patcher | |
| /lib/security/.config/pg | |
| /lib/security/.config/crypt | |
| /lib/security/.config/utime | |
| /lib/security/.config/wget | |
| /lib/security/.config/instmod | |
| /lib/security/.config/bin/find | |
| /lib/security/.config/bin/du | |
| /lib/security/.config/bin/ls | |
| /lib/security/.config/bin/psr | |
| /lib/security/.config/bin/netstat | |
| /lib/security/.config/bin/su | |
| /lib/security/.config/bin/ping | |
| /lib/security/.config/bin/passwd" | |
| ILLOGIC_DIRS="/lib/security/.config | |
| /lib/security/.config/ssh | |
| /lib/security/.config/bin | |
| /lib/security/.config/backup | |
| /root/%%%/.dir | |
| /root/%%%/.dir/mass-scan | |
| /root/%%%/.dir/flood" | |
| ILLOGIC_KSYMS= | |
| # OSX Inqtana (Variant A) | |
| INQTANAA_FILES="/Users/w0rm-support.tgz | |
| /Users/InqTest.class | |
| /Users/com.openbundle.plist | |
| /Users/com.pwned.plist | |
| /Users/libavetanaBT.jnilib" | |
| INQTANAA_DIRS="/Users/de | |
| /Users/javax" | |
| INQTANAA_KSYMS= | |
| # OSX Inqtana (Variant B) | |
| INQTANAB_FILES="/Users/w0rms.love.apples.tgz | |
| /Users/InqTest.class | |
| /Users/InqTest.java | |
| /Users/libavetanaBT.jnilib | |
| /Users/InqTanaHandler | |
| /Users/InqTanaHandler.bundle" | |
| INQTANAB_DIRS="/Users/de | |
| /Users/javax" | |
| INQTANAB_KSYMS= | |
| # OSX Inqtana (Variant C) | |
| INQTANAC_FILES="/Users/applec0re.tgz | |
| /Users/InqTest.class | |
| /Users/InqTest.java | |
| /Users/libavetanaBT.jnilib | |
| /Users/environment.plist | |
| /Users/pwned.c | |
| /Users/pwned.dylib" | |
| INQTANAC_DIRS="/Users/de | |
| /Users/javax" | |
| INQTANAC_KSYMS= | |
| # IntoXonia-NG Rootkit | |
| INTOXONIA_FILES= | |
| INTOXONIA_DIRS= | |
| INTOXONIA_KSYMS="funces | |
| ixinit | |
| tricks | |
| kernel_unlink | |
| rootme | |
| hide_module | |
| find_sys_call_tbl" | |
| # Irix Rootkit (for Irix 6.x) | |
| IRIXRK_FILES= | |
| IRIXRK_DIRS="/dev/pts/01 | |
| /dev/pts/01/backup | |
| /dev/pts/01/etc | |
| /dev/pts/01/tmp" | |
| IRIXRK_KSYMS= | |
| # Jynx Rootkit | |
| JYNX_FILES="/xochikit/bc | |
| /xochikit/ld_poison.so | |
| /omgxochi/bc | |
| /omgxochi/ld_poison.so | |
| /var/local/^^/bc | |
| /var/local/^^/ld_poison.so" | |
| JYNX_DIRS="/xochikit | |
| /omgxochi | |
| /var/local/^^" | |
| JYNX_KSYMS= | |
| # Jynx2 Rootkit | |
| JYNX2_FILES="/XxJynx/reality.so" | |
| JYNX2_DIRS="/XxJynx" | |
| JYNX2_KSYMS= | |
| # KBeast (Kernel Beast) Rootkit | |
| KBEAST_FILES="/usr/_h4x_/ipsecs-kbeast-v1.ko | |
| /usr/_h4x_/_h4x_bd | |
| /usr/_h4x_/acctlog" | |
| KBEAST_DIRS="/usr/_h4x_" | |
| KBEAST_KSYMS="h4x_delete_module | |
| h4x_getdents64 | |
| h4x_kill | |
| h4x_open | |
| h4x_read | |
| h4x_rename | |
| h4x_rmdir | |
| h4x_tcp4_seq_show | |
| h4x_write" | |
| # OSX Keydnap backdoor | |
| # The '%' character represents a space. | |
| KEYDNAP_FILES="/Applications/Transmission.app/Contents/Resources/License.rtf | |
| /Volumes/Transmission/Transmission.app/Contents/Resources/License.rtf | |
| /Library/LaunchAgents/com.apple.iCloud.sync.daemon.plist | |
| /Library/LaunchAgents/com.geticloud.icloud.photo.plist" | |
| KEYDNAP_DIRS="/Library/Application%Support/com.apple.iCloud.sync.daemon/" | |
| KEYDNAP_KSYMS= | |
| # Kitko Rootkit | |
| KITKO_FILES= | |
| KITKO_DIRS="/usr/src/redhat/SRPMS/..." | |
| KITKO_KSYMS= | |
| # Knark Rootkit | |
| KNARK_FILES="/proc/knark/pids" | |
| KNARK_DIRS="/proc/knark" | |
| KNARK_KSYMS= | |
| # OSX Komplex Trojan | |
| KOMPLEX_FILES="/Users/Shared/.local/kextd | |
| /Users/Shared/com.apple.updates.plist | |
| /Users/Shared/start.sh" | |
| KOMPLEX_DIRS= | |
| KOMPLEX_KSYMS= | |
| # ld-linuxv.so (LD_PRELOAD shared library rootkit) | |
| LINUXV_FILES="/lib/ld-linuxv.so.1" | |
| LINUXV_DIRS="/var/opt/_so_cache | |
| /var/opt/_so_cache/ld | |
| /var/opt/_so_cache/lc" | |
| LINUXV_KSYMS= | |
| # Lion Worm | |
| LION_FILES="/bin/in.telnetd | |
| /bin/mjy | |
| /usr/man/man1/man1/lib/.lib/mjy | |
| /usr/man/man1/man1/lib/.lib/in.telnetd | |
| /usr/man/man1/man1/lib/.lib/.x | |
| /dev/.lib/lib/scan/1i0n.sh | |
| /dev/.lib/lib/scan/hack.sh | |
| /dev/.lib/lib/scan/bind | |
| /dev/.lib/lib/scan/randb | |
| /dev/.lib/lib/scan/scan.sh | |
| /dev/.lib/lib/scan/pscan | |
| /dev/.lib/lib/scan/star.sh | |
| /dev/.lib/lib/scan/bindx.sh | |
| /dev/.lib/lib/scan/bindname.log | |
| /dev/.lib/lib/1i0n.sh | |
| /dev/.lib/lib/lib/netstat | |
| /dev/.lib/lib/lib/dev/.1addr | |
| /dev/.lib/lib/lib/dev/.1logz | |
| /dev/.lib/lib/lib/dev/.1proc | |
| /dev/.lib/lib/lib/dev/.1file" | |
| LION_DIRS= | |
| LION_KSYMS= | |
| # Lockit Rootkit (aka LJK2) | |
| LOCKIT_FILES="/usr/lib/libmen.oo/.LJK2/ssh_config | |
| /usr/lib/libmen.oo/.LJK2/ssh_host_key | |
| /usr/lib/libmen.oo/.LJK2/ssh_host_key.pub | |
| /usr/lib/libmen.oo/.LJK2/ssh_random_seed* | |
| /usr/lib/libmen.oo/.LJK2/sshd_config | |
| /usr/lib/libmen.oo/.LJK2/backdoor/RK1bd | |
| /usr/lib/libmen.oo/.LJK2/backup/du | |
| /usr/lib/libmen.oo/.LJK2/backup/ifconfig | |
| /usr/lib/libmen.oo/.LJK2/backup/inetd.conf | |
| /usr/lib/libmen.oo/.LJK2/backup/locate | |
| /usr/lib/libmen.oo/.LJK2/backup/login | |
| /usr/lib/libmen.oo/.LJK2/backup/ls | |
| /usr/lib/libmen.oo/.LJK2/backup/netstat | |
| /usr/lib/libmen.oo/.LJK2/backup/ps | |
| /usr/lib/libmen.oo/.LJK2/backup/pstree | |
| /usr/lib/libmen.oo/.LJK2/backup/rc.sysinit | |
| /usr/lib/libmen.oo/.LJK2/backup/syslogd | |
| /usr/lib/libmen.oo/.LJK2/backup/tcpd | |
| /usr/lib/libmen.oo/.LJK2/backup/top | |
| /usr/lib/libmen.oo/.LJK2/clean/RK1sauber | |
| /usr/lib/libmen.oo/.LJK2/clean/RK1wted | |
| /usr/lib/libmen.oo/.LJK2/hack/RK1parse | |
| /usr/lib/libmen.oo/.LJK2/hack/RK1sniff | |
| /usr/lib/libmen.oo/.LJK2/hide/.RK1addr | |
| /usr/lib/libmen.oo/.LJK2/hide/.RK1dir | |
| /usr/lib/libmen.oo/.LJK2/hide/.RK1log | |
| /usr/lib/libmen.oo/.LJK2/hide/.RK1proc | |
| /usr/lib/libmen.oo/.LJK2/hide/RK1phidemod.c | |
| /usr/lib/libmen.oo/.LJK2/modules/README.modules | |
| /usr/lib/libmen.oo/.LJK2/modules/RK1hidem.c | |
| /usr/lib/libmen.oo/.LJK2/modules/RK1phide | |
| /usr/lib/libmen.oo/.LJK2/sshconfig/RK1ssh" | |
| LOCKIT_DIRS="/usr/lib/libmen.oo/.LJK2" | |
| LOCKIT_KSYMS= | |
| # Mokes backdoor | |
| MOKES_FILES="/tmp/ss0-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9].sst | |
| /tmp/aa0-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9].aat | |
| /tmp/kk0-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9].kkt | |
| /tmp/dd0-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9].ddt" | |
| MOKES_DIRS= | |
| MOKES_KSYMS= | |
| # MRK (MiCrobul?) RootKit (based on Devil RootKit, also see Xzibit) | |
| MRK_FILES="/dev/ida/.inet/pid | |
| /dev/ida/.inet/ssh_host_key | |
| /dev/ida/.inet/ssh_random_seed | |
| /dev/ida/.inet/tcp.log" | |
| MRK_DIRS="/dev/ida/.inet | |
| /var/spool/cron/.sh" | |
| MRK_KSYMS= | |
| # Mood-NT Rootkit | |
| # Binary is by default called "mood-nt" but can be anywhere. | |
| # Here we look for collaterals, from include/prefs.h defaults | |
| # until sig-based dirscan() is added. | |
| MOODNT_FILES="/sbin/init__mood-nt-_-_cthulhu | |
| /_cthulhu/mood-nt.init | |
| /_cthulhu/mood-nt.conf | |
| /_cthulhu/mood-nt.sniff" | |
| MOODNT_DIRS="/_cthulhu" | |
| MOODNT_KSYMS= | |
| # Ni0 Rootkit | |
| NIO_FILES="/var/lock/subsys/...datafile.../...net... | |
| /var/lock/subsys/...datafile.../...port... | |
| /var/lock/subsys/...datafile.../...ps... | |
| /var/lock/subsys/...datafile.../...file..." | |
| NIO_DIRS="/tmp/waza | |
| /var/lock/subsys/...datafile... | |
| /usr/sbin/es" | |
| NIO_KSYMS= | |
| # Ohhara Rootkit | |
| OHHARA_FILES="/var/lock/subsys/...datafile.../...datafile.../in.smbd.log" | |
| OHHARA_DIRS="/var/lock/subsys/...datafile... | |
| /var/lock/subsys/...datafile.../...datafile... | |
| /var/lock/subsys/...datafile.../...datafile.../bin | |
| /var/lock/subsys/...datafile.../...datafile.../usr/bin | |
| /var/lock/subsys/...datafile.../...datafile.../usr/sbin | |
| /var/lock/subsys/...datafile.../...datafile.../lib/security" | |
| OHHARA_KSYMS= | |
| # Optic Kit (Tux variant) Rootkit | |
| OPTICKIT_FILES= | |
| OPTICKIT_DIRS="/dev/tux | |
| /usr/bin/xchk | |
| /usr/bin/xsf | |
| /usr/bin/ssh2d" | |
| OPTICKIT_KSYMS= | |
| # OSX Rootkit 0.2.1 (OSXRK) | |
| OSXRK_FILES="/dev/.rk/nc | |
| /dev/.rk/diepu | |
| /dev/.rk/backd | |
| /Library/StartupItems/opener | |
| /Library/StartupItems/opener.sh | |
| /System/Library/StartupItems/opener | |
| /System/Library/StartupItems/opener.sh" | |
| OSXRK_DIRS="/dev/.rk | |
| /Users/LDAP-daemon | |
| /tmp/.work" | |
| OSXRK_KSYMS= | |
| # Oz Rootkit | |
| OZ_FILES="/dev/.oz/.nap/rkit/terror" | |
| OZ_DIRS="/dev/.oz" | |
| OZ_KSYMS= | |
| # Phalanx Rootkit | |
| PHALANX_FILES="/uNFuNF | |
| /etc/host.ph1 | |
| /bin/host.ph1 | |
| /usr/share/.home.ph1/phalanx | |
| /usr/share/.home.ph1/cb | |
| /usr/share/.home.ph1/kebab" | |
| PHALANX_DIRS="/usr/share/.home.ph1 | |
| /usr/share/.home.ph1/tty" | |
| PHALANX_KSYMS= | |
| # Phalanx2 Rootkit | |
| PHALANX2_FILES="/etc/khubd.p2/.p2rc | |
| /etc/khubd.p2/.phalanx2 | |
| /etc/khubd.p2/.sniff | |
| /etc/khubd.p2/sshgrab.py | |
| /etc/lolzz.p2/.p2rc | |
| /etc/lolzz.p2/.phalanx2 | |
| /etc/lolzz.p2/.sniff | |
| /etc/lolzz.p2/sshgrab.py | |
| /etc/cron.d/zupzzplaceholder | |
| /usr/lib/zupzz.p2/.p-2.3d | |
| /usr/lib/zupzz.p2/.p2rc" | |
| PHALANX2_DIRS="/etc/khubd.p2 | |
| /etc/lolzz.p2 | |
| /usr/lib/zupzz.p2" | |
| PHALANX2_KSYMS= | |
| # Portacelo Rootkit | |
| PORTACELO_FILES="/var/lib/.../.ak | |
| /var/lib/.../.hk | |
| /var/lib/.../.rs | |
| /var/lib/.../.p | |
| /var/lib/.../getty | |
| /var/lib/.../lkt.o | |
| /var/lib/.../show | |
| /var/lib/.../nlkt.o | |
| /var/lib/.../ssshrc | |
| /var/lib/.../sssh_equiv | |
| /var/lib/.../sssh_known_hosts | |
| /var/lib/.../sssh_pid ~/.sssh/known_hosts" | |
| PORTACELO_DIRS= | |
| PORTACELO_KSYMS= | |
| # OSX Proton backdoor | |
| PROTON_FILES="/Library/LaunchAgents/com.apple.xpcd.plist | |
| /Library/LaunchAgents/com.Eltima.UpdaterAgent.plist | |
| /Library/.rand/updateragent.app | |
| /tmp/Updater.app" | |
| PROTON_DIRS="/Library/.rand | |
| /Library/.cachedir | |
| /Library/.random" | |
| PROTON_KSYMS= | |
| # R3dstorm Toolkit | |
| REDSTORM_FILES="/var/log/tk02/see_all | |
| /var/log/tk02/.scris | |
| /bin/.../sshd/sbin/sshd1 | |
| /bin/.../hate/sk | |
| /bin/.../see_all" | |
| REDSTORM_DIRS="/var/log/tk02 | |
| /var/log/tk02/old | |
| /bin/..." | |
| REDSTORM_KSYMS= | |
| # RH-Sharpe's Rootkit | |
| RHSHARPES_FILES="/bin/lps | |
| /usr/bin/lpstree | |
| /usr/bin/ltop | |
| /usr/bin/lkillall | |
| /usr/bin/ldu | |
| /usr/bin/lnetstat | |
| /usr/bin/wp | |
| /usr/bin/shad | |
| /usr/bin/vadim | |
| /usr/bin/slice | |
| /usr/bin/cleaner | |
| /usr/include/rpcsvc/du" | |
| RHSHARPES_DIRS= | |
| RHSHARPES_KSYMS= | |
| # RSHA's Rootkit | |
| RSHA_FILES="/bin/kr4p | |
| /usr/bin/n3tstat | |
| /usr/bin/chsh2 | |
| /usr/bin/slice2 | |
| /usr/src/linux/arch/alpha/lib/.lib/.1proc | |
| /etc/rc.d/arch/alpha/lib/.lib/.1addr" | |
| RSHA_DIRS="/etc/rc.d/rsha | |
| /etc/rc.d/arch/alpha/lib/.lib" | |
| RSHA_KSYMS= | |
| # Shutdown Rootkit | |
| # The '%' character represents a space. | |
| SHUTDOWN_FILES="/usr/man/man5/..%/.dir/scannah/asus | |
| /usr/man/man5/..%/.dir/see | |
| /usr/man/man5/..%/.dir/nscd | |
| /usr/man/man5/..%/.dir/alpd | |
| /etc/rc.d/rc.local%" | |
| SHUTDOWN_DIRS="/usr/man/man5/..%/.dir | |
| /usr/man/man5/..%/.dir/scannah | |
| /etc/rc.d/rc0.d/..%/.dir" | |
| SHUTDOWN_KSYMS= | |
| # Scalper (FreeBSD.Scalper.Worm) Worm | |
| SCALPER_FILES="/tmp/.a | |
| /tmp/.uua" | |
| SCALPER_DIRS= | |
| SCALPER_KSYMS= | |
| # SHV4 Rootkit | |
| SHV4_FILES="/etc/ld.so.hash | |
| /lib/libext-2.so.7 | |
| /lib/lidps1.so | |
| /lib/libproc.a | |
| /lib/libproc.so.2.0.6 | |
| /lib/ldd.so/tks | |
| /lib/ldd.so/tkp | |
| /lib/ldd.so/tksb | |
| /lib/security/.config/sshd | |
| /lib/security/.config/ssh/ssh_host_key | |
| /lib/security/.config/ssh/ssh_host_key.pub | |
| /lib/security/.config/ssh/ssh_random_seed | |
| /usr/include/file.h | |
| /usr/include/hosts.h | |
| /usr/include/lidps1.so | |
| /usr/include/log.h | |
| /usr/include/proc.h | |
| /usr/sbin/xntps | |
| /dev/srd0" | |
| SHV4_DIRS="/lib/ldd.so | |
| /lib/security/.config | |
| /lib/security/.config/ssh" | |
| SHV4_KSYMS= | |
| # SHV5 Rootkit | |
| SHV5_FILES="/etc/sh.conf | |
| /lib/libproc.a | |
| /lib/libproc.so.2.0.6 | |
| /lib/lidps1.so | |
| /lib/libsh.so/bash | |
| /usr/include/file.h | |
| /usr/include/hosts.h | |
| /usr/include/log.h | |
| /usr/include/proc.h | |
| /lib/libsh.so/shdcf2 | |
| /lib/libsh.so/shhk | |
| /lib/libsh.so/shhk.pub | |
| /lib/libsh.so/shrs | |
| /usr/lib/libsh/.bashrc | |
| /usr/lib/libsh/shsb | |
| /usr/lib/libsh/hide | |
| /usr/lib/libsh/.sniff/shsniff | |
| /usr/lib/libsh/.sniff/shp | |
| /dev/srd0" | |
| SHV5_DIRS="/lib/libsh.so | |
| /usr/lib/libsh | |
| /usr/lib/libsh/utilz | |
| /usr/lib/libsh/.backup" | |
| SHV5_KSYMS= | |
| # Sin Rootkit | |
| SINROOTKIT_FILES="/dev/.haos/haos1/.f/Denyed | |
| /dev/ttyoa | |
| /dev/ttyof | |
| /dev/ttyop | |
| /dev/ttyos | |
| /usr/lib/.lib | |
| /usr/lib/sn/.X | |
| /usr/lib/sn/.sys | |
| /usr/lib/ld/.X | |
| /usr/man/man1/... | |
| /usr/man/man1/.../.m | |
| /usr/man/man1/.../.w" | |
| SINROOTKIT_DIRS="/usr/lib/sn | |
| /usr/lib/man1/... | |
| /dev/.haos" | |
| SINROOTKIT_KSYMS= | |
| # Slapper Worm | |
| SLAPPER_FILES="/tmp/.bugtraq | |
| /tmp/.uubugtraq | |
| /tmp/.bugtraq.c | |
| /tmp/httpd | |
| /tmp/.unlock | |
| /tmp/update | |
| /tmp/.cinik | |
| /tmp/.b" | |
| SLAPPER_DIRS= | |
| SLAPPER_KSYMS= | |
| # Sneakin Rootkit | |
| SNEAKIN_FILES= | |
| SNEAKIN_DIRS="/tmp/.X11-unix/.../rk" | |
| SNEAKIN_KSYMS= | |
| # Solaris Wanuk backdoor | |
| WANUKDOOR_FILES="/var/adm/sa/.adm/.lp-door.i86pc | |
| /var/adm/sa/.adm/.lp-door.sun4 | |
| /var/spool/lp/admins/.lp-door.i86pc | |
| /var/spool/lp/admins/.lp-door.sun4 | |
| /var/spool/lp/admins/lpshut | |
| /var/spool/lp/admins/lpsystem | |
| /var/spool/lp/admins/lpadmin | |
| /var/spool/lp/admins/lpmove | |
| /var/spool/lp/admins/lpusers | |
| /var/spool/lp/admins/lpfilter | |
| /var/spool/lp/admins/lpstat | |
| /var/spool/lp/admins/lpd | |
| /var/spool/lp/admins/lpsched | |
| /var/spool/lp/admins/lpc" | |
| WANUKDOOR_DIRS="/var/adm/sa/.adm" | |
| WANUKDOOR_KSYMS= | |
| # Solaris Wanuk Worm (ELF_WANUK.A) | |
| WANUKWORM_FILES="/var/adm/.adm | |
| /var/adm/.i86pc | |
| /var/adm/.sun4 | |
| /var/adm/sa/.adm | |
| /var/adm/sa/.adm/.i86pc | |
| /var/adm/sa/.adm/.sun4 | |
| /var/adm/sa/.adm/.crontab | |
| /var/adm/sa/.adm/devfsadmd | |
| /var/adm/sa/.adm/svcadm | |
| /var/adm/sa/.adm/cfgadm | |
| /var/adm/sa/.adm/kadmind | |
| /var/adm/sa/.adm/zoneadmd | |
| /var/adm/sa/.adm/sadm | |
| /var/adm/sa/.adm/sysadm | |
| /var/adm/sa/.adm/dladm | |
| /var/adm/sa/.adm/bootadm | |
| /var/adm/sa/.adm/routeadm | |
| /var/adm/sa/.adm/uadmin | |
| /var/adm/sa/.adm/acctadm | |
| /var/adm/sa/.adm/cryptoadm | |
| /var/adm/sa/.adm/inetadm | |
| /var/adm/sa/.adm/logadm | |
| /var/adm/sa/.adm/nlsadmin | |
| /var/adm/sa/.adm/sacadm | |
| /var/adm/sa/.adm/syseventadmd | |
| /var/adm/sa/.adm/ttyadmd | |
| /var/adm/sa/.adm/consadmd | |
| /var/adm/sa/.adm/metadevadm | |
| /var/adm/sa/.i86pc | |
| /var/adm/sa/.sun4 | |
| /var/adm/sa/acctadm | |
| /var/adm/sa/bootadm | |
| /var/adm/sa/cfgadm | |
| /var/adm/sa/consadmd | |
| /var/adm/sa/cryptoadm | |
| /var/adm/sa/devfsadmd | |
| /var/adm/sa/dladm | |
| /var/adm/sa/inetadm | |
| /var/adm/sa/kadmind | |
| /var/adm/sa/logadm | |
| /var/adm/sa/metadevadm | |
| /var/adm/sa/nlsadmin | |
| /var/adm/sa/routeadm | |
| /var/adm/sa/sacadm | |
| /var/adm/sa/sadm | |
| /var/adm/sa/svcadm | |
| /var/adm/sa/sysadm | |
| /var/adm/sa/syseventadmd | |
| /var/adm/sa/ttyadmd | |
| /var/adm/sa/uadmin | |
| /var/adm/sa/zoneadmd | |
| /var/spool/lp/admins/.lp/.crontab | |
| /var/spool/lp/admins/.lp/lpshut | |
| /var/spool/lp/admins/.lp/lpsystem | |
| /var/spool/lp/admins/.lp/lpadmin | |
| /var/spool/lp/admins/.lp/lpmove | |
| /var/spool/lp/admins/.lp/lpusers | |
| /var/spool/lp/admins/.lp/lpfilter | |
| /var/spool/lp/admins/.lp/lpstat | |
| /var/spool/lp/admins/.lp/lpd | |
| /var/spool/lp/admins/.lp/lpsched | |
| /var/spool/lp/admins/.lp/lpc" | |
| WANUKWORM_DIRS="/var/adm/sa/.adm | |
| /var/spool/lp/admins/.lp" | |
| WANUKWORM_KSYMS= | |
| # 'Spanish' Rootkit | |
| SPANISH_FILES="/dev/ptyq | |
| /bin/ad | |
| /bin/ava | |
| /bin/server | |
| /usr/sbin/rescue | |
| /usr/share/.../chrps | |
| /usr/share/.../chrifconfig | |
| /usr/share/.../netstat | |
| /usr/share/.../linsniffer | |
| /usr/share/.../charbd | |
| /usr/share/.../charbd2 | |
| /usr/share/.../charbd3 | |
| /usr/share/.../charbd4 | |
| /usr/man/tmp/update.tgz | |
| /var/lib/rpm/db.rpm | |
| /var/cache/man/.cat | |
| /var/spool/lpd/remote/.lpq" | |
| SPANISH_DIRS="/usr/share/..." | |
| SPANISH_KSYMS= | |
| # Suckit Rootkit | |
| SUCKIT_FILES="/sbin/initsk12 | |
| /sbin/initxrk | |
| /usr/bin/null | |
| /usr/share/locale/sk/.sk12/sk | |
| /etc/rc.d/rc0.d/S23kmdac | |
| /etc/rc.d/rc1.d/S23kmdac | |
| /etc/rc.d/rc2.d/S23kmdac | |
| /etc/rc.d/rc3.d/S23kmdac | |
| /etc/rc.d/rc4.d/S23kmdac | |
| /etc/rc.d/rc5.d/S23kmdac | |
| /etc/rc.d/rc6.d/S23kmdac" | |
| SUCKIT_DIRS="/dev/sdhu0/tehdrakg | |
| /etc/.MG | |
| /usr/share/locale/sk/.sk12 | |
| /usr/lib/perl5/site_perl/i386-linux/auto/TimeDate/.packlist" | |
| SUCKIT_KSYMS= | |
| # SunOS / NSDAP Rootkit | |
| NSDAP_FILES="/dev/pts/01/55su | |
| /dev/pts/01/55ps | |
| /dev/pts/01/55ping | |
| /dev/pts/01/55login | |
| /dev/pts/01/PATCHER_COMPLETED | |
| /dev/prom/sn.l | |
| /dev/prom/dos | |
| /usr/lib/vold/nsdap/.kit | |
| /usr/lib/vold/nsdap/defines | |
| /usr/lib/vold/nsdap/patcher | |
| /usr/lib/vold/nsdap/pg | |
| /usr/lib/vold/nsdap/cleaner | |
| /usr/lib/vold/nsdap/utime | |
| /usr/lib/vold/nsdap/crypt | |
| /usr/lib/vold/nsdap/findkit | |
| /usr/lib/vold/nsdap/sn2 | |
| /usr/lib/vold/nsdap/sniffload | |
| /usr/lib/vold/nsdap/runsniff | |
| /usr/lib/lpset | |
| /usr/lib/lpstart | |
| /usr/bin/mc68000 | |
| /usr/bin/mc68010 | |
| /usr/bin/mc68020 | |
| /usr/ucb/bin/ps | |
| /usr/bin/m68k | |
| /usr/bin/sun2 | |
| /usr/bin/mc68030 | |
| /usr/bin/mc68040 | |
| /usr/bin/sun3 | |
| /usr/bin/sun3x | |
| /usr/bin/lso | |
| /usr/bin/u370" | |
| NSDAP_DIRS="/dev/pts/01 | |
| /dev/prom | |
| /usr/lib/vold/nsdap | |
| /.pat" | |
| NSDAP_KSYMS= | |
| # SunOS Rootkit | |
| SUNOSROOTKIT_FILES="/etc/ld.so.hash | |
| /lib/libext-2.so.7 | |
| /usr/bin/ssh2d | |
| /bin/xlogin | |
| /usr/lib/crth.o | |
| /usr/lib/crtz.o | |
| /sbin/login | |
| /lib/security/.config/sn | |
| /lib/security/.config/lpsched | |
| /dev/kmod | |
| /dev/dos" | |
| SUNOSROOTKIT_DIRS= | |
| SUNOSROOTKIT_KSYMS= | |
| # Superkit Rootkit (Suckit 1.3b-based) | |
| SUPERKIT_FILES="/usr/man/.sman/sk/backsh | |
| /usr/man/.sman/sk/izbtrag | |
| /usr/man/.sman/sk/sksniff | |
| /var/www/cgi-bin/cgiback.cgi" | |
| SUPERKIT_DIRS="/usr/man/.sman/sk" | |
| SUPERKIT_KSYMS= | |
| # Telnet Backdoor | |
| TBD_FILES="/usr/lib/.tbd" | |
| TBD_DIRS= | |
| TBD_KSYMS= | |
| # TeLeKiT Rootkit | |
| TELEKIT_FILES="/usr/man/man3/.../TeLeKiT/bin/sniff | |
| /usr/man/man3/.../TeLeKiT/bin/telnetd | |
| /usr/man/man3/.../TeLeKiT/bin/teleulo | |
| /usr/man/man3/.../cl | |
| /dev/ptyr | |
| /dev/ptyp | |
| /dev/ptyq | |
| /dev/hda06 | |
| /usr/info/libc1.so" | |
| TELEKIT_DIRS="/usr/man/man3/... | |
| /usr/man/man3/.../lsniff | |
| /usr/man/man3/.../TeLeKiT" | |
| TELEKIT_KSYMS= | |
| # OSX Togroot Rootkit | |
| TOGROOT_FILES="/System/Library/Extensions/Togroot.kext/Contents/Info.plist | |
| /System/Library/Extensions/Togroot.kext/Contents/pbdevelopment.plist | |
| /System/Library/Extensions/Togroot.kext/Contents/MacOS/togrootkext" | |
| TOGROOT_DIRS="/System/Library/Extensions/Togroot.kext | |
| /System/Library/Extensions/Togroot.kext/Contents | |
| /System/Library/Extensions/Togroot.kext/Contents/MacOS" | |
| TOGROOT_KSYMS= | |
| # T0rn (and misc) Rootkit | |
| TORN_FILES="/dev/.lib/lib/lib/t0rns | |
| /dev/.lib/lib/lib/du | |
| /dev/.lib/lib/lib/ls | |
| /dev/.lib/lib/lib/t0rnsb | |
| /dev/.lib/lib/lib/ps | |
| /dev/.lib/lib/lib/t0rnp | |
| /dev/.lib/lib/lib/find | |
| /dev/.lib/lib/lib/ifconfig | |
| /dev/.lib/lib/lib/pg | |
| /dev/.lib/lib/lib/ssh.tgz | |
| /dev/.lib/lib/lib/top | |
| /dev/.lib/lib/lib/sz | |
| /dev/.lib/lib/lib/login | |
| /dev/.lib/lib/lib/in.fingerd | |
| /dev/.lib/lib/lib/1i0n.sh | |
| /dev/.lib/lib/lib/pstree | |
| /dev/.lib/lib/lib/in.telnetd | |
| /dev/.lib/lib/lib/mjy | |
| /dev/.lib/lib/lib/sush | |
| /dev/.lib/lib/lib/tfn | |
| /dev/.lib/lib/lib/name | |
| /dev/.lib/lib/lib/getip.sh | |
| /usr/info/.torn/sh* | |
| /usr/src/.puta/.1addr | |
| /usr/src/.puta/.1file | |
| /usr/src/.puta/.1proc | |
| /usr/src/.puta/.1logz | |
| /usr/info/.t0rn" | |
| TORN_DIRS="/dev/.lib | |
| /dev/.lib/lib | |
| /dev/.lib/lib/lib | |
| /dev/.lib/lib/lib/dev | |
| /dev/.lib/lib/scan | |
| /usr/src/.puta | |
| /usr/man/man1/man1 | |
| /usr/man/man1/man1/lib | |
| /usr/man/man1/man1/lib/.lib | |
| /usr/man/man1/man1/lib/.lib/.backup" | |
| TORN_KSYMS= | |
| # trNkit Rootkit | |
| TRNKIT_FILES="/usr/lib/libbins.la | |
| /usr/lib/libtcs.so | |
| /dev/.ttpy/ulogin.sh | |
| /dev/.ttpy/tcpshell.sh | |
| /dev/.ttpy/bupdu | |
| /dev/.ttpy/buloc | |
| /dev/.ttpy/buloc1 | |
| /dev/.ttpy/buloc2 | |
| /dev/.ttpy/stat | |
| /dev/.ttpy/backps | |
| /dev/.ttpy/tree | |
| /dev/.ttpy/topk | |
| /dev/.ttpy/wold | |
| /dev/.ttpy/whoold | |
| /dev/.ttpy/backdoors" | |
| TRNKIT_DIRS= | |
| TRNKIT_KSYMS= | |
| # Trojanit Kit Rootkit | |
| TROJANIT_FILES="/bin/.ls | |
| /bin/.ps | |
| /bin/.netstat | |
| /usr/bin/.nop | |
| /usr/bin/.who" | |
| TROJANIT_DIRS= | |
| TROJANIT_KSYMS= | |
| # Turtle / Turtle2 Rootkit | |
| TURTLE_FILES="/dev/turtle2dev" | |
| TURTLE_DIRS= | |
| TURTLE_KSYMS= | |
| # Tuxtendo (Tuxkit) Rootkit | |
| TUXTENDO_FILES="/lib/libproc.so.2.0.7 | |
| /usr/bin/xchk | |
| /usr/bin/xsf | |
| /dev/tux/suidsh | |
| /dev/tux/.addr | |
| /dev/tux/.cron | |
| /dev/tux/.file | |
| /dev/tux/.log | |
| /dev/tux/.proc | |
| /dev/tux/.iface | |
| /dev/tux/.pw | |
| /dev/tux/.df | |
| /dev/tux/.ssh | |
| /dev/tux/.tux | |
| /dev/tux/ssh2/sshd2_config | |
| /dev/tux/ssh2/hostkey | |
| /dev/tux/ssh2/hostkey.pub | |
| /dev/tux/ssh2/logo | |
| /dev/tux/ssh2/random_seed | |
| /dev/tux/backup/crontab | |
| /dev/tux/backup/df | |
| /dev/tux/backup/dir | |
| /dev/tux/backup/find | |
| /dev/tux/backup/ifconfig | |
| /dev/tux/backup/locate | |
| /dev/tux/backup/netstat | |
| /dev/tux/backup/ps | |
| /dev/tux/backup/pstree | |
| /dev/tux/backup/syslogd | |
| /dev/tux/backup/tcpd | |
| /dev/tux/backup/top | |
| /dev/tux/backup/updatedb | |
| /dev/tux/backup/vdir" | |
| TUXTENDO_DIRS="/dev/tux | |
| /dev/tux/ssh2 | |
| /dev/tux/backup" | |
| TUXTENDO_KSYMS= | |
| # Universal Rootkit by K2 (URK) Release 0.9.8 | |
| URK_FILES="/dev/prom/sn.l | |
| /usr/lib/ldlibps.so | |
| /usr/lib/ldlibnet.so | |
| /dev/pts/01/uconf.inv | |
| /dev/pts/01/cleaner | |
| /dev/pts/01/bin/psniff | |
| /dev/pts/01/bin/du | |
| /dev/pts/01/bin/ls | |
| /dev/pts/01/bin/passwd | |
| /dev/pts/01/bin/ps | |
| /dev/pts/01/bin/psr | |
| /dev/pts/01/bin/su | |
| /dev/pts/01/bin/find | |
| /dev/pts/01/bin/netstat | |
| /dev/pts/01/bin/ping | |
| /dev/pts/01/bin/strings | |
| /dev/pts/01/bin/bash | |
| /usr/man/man1/xxxxxxbin/du | |
| /usr/man/man1/xxxxxxbin/ls | |
| /usr/man/man1/xxxxxxbin/passwd | |
| /usr/man/man1/xxxxxxbin/ps | |
| /usr/man/man1/xxxxxxbin/psr | |
| /usr/man/man1/xxxxxxbin/su | |
| /usr/man/man1/xxxxxxbin/find | |
| /usr/man/man1/xxxxxxbin/netstat | |
| /usr/man/man1/xxxxxxbin/ping | |
| /usr/man/man1/xxxxxxbin/strings | |
| /usr/man/man1/xxxxxxbin/bash | |
| /tmp/conf.inv" | |
| URK_DIRS="/dev/prom | |
| /dev/pts/01 | |
| /dev/pts/01/bin | |
| /usr/man/man1/xxxxxxbin" | |
| URK_KSYMS= | |
| # Also-see: /usr/lib/lpset (esniff), /var/lp/lpacct/ (files), /usr/lib/bnclp, /usr/lib/lpsys (identd), | |
| # Also-see: /usr/lib/lptd (backdoor?), /sbin/rc2 and /sbin/rc3 containing string "/usr/lib/lpstart", | |
| # Also-see: dos, psbnc, lpacct, USER, lp, | |
| # Also see: /etc/lpconfig vs /etc/ttyhash, uconv.inv vs urk.conf. | |
| # VcKit Rootkit | |
| VCKIT_FILES= | |
| VCKIT_DIRS="/usr/include/linux/modules/lib.so | |
| /usr/include/linux/modules/lib.so/bin" | |
| VCKIT_KSYMS= | |
| # Vampire Rootkit | |
| VAMPIRE_FILES= | |
| VAMPIRE_DIRS= | |
| VAMPIRE_KSYMS="new_getdents | |
| old_getdents | |
| should_hide_file_name | |
| should_hide_task_name" | |
| # Volc Rootkit | |
| # Omit listing system binaries that should be picked up by changed hashes. | |
| VOLC_FILES="/usr/bin/volc | |
| /usr/lib/volc/backdoor/divine | |
| /usr/lib/volc/linsniff | |
| /etc/rc.d/rc1.d/S25sysconf | |
| /etc/rc.d/rc2.d/S25sysconf | |
| /etc/rc.d/rc3.d/S25sysconf | |
| /etc/rc.d/rc4.d/S25sysconf | |
| /etc/rc.d/rc5.d/S25sysconf" | |
| VOLC_DIRS="/var/spool/.recent | |
| /var/spool/.recent/.files | |
| /usr/lib/volc | |
| /usr/lib/volc/backup" | |
| VOLC_KSYMS= | |
| # weaponX 0.1 | |
| WEAPONX_FILES="/System/Library/Extensions/WeaponX.kext" | |
| WEAPONX_DIRS="/tmp/..." | |
| WEAPONX_KSYMS= | |
| # WMKR26 2.0, WindEX, XND Crew, LKM for kernel 2.6 | |
| # (2.6.12 - 2.6.19.2, i[456]86 and x86_64) | |
| # These files don't exist and can't be seen: | |
| # /proc/qwerty | |
| # /proc/givemeroot | |
| # /proc/hide+[PID] | |
| # /proc/hide-[PID] | |
| # /proc/active- | |
| # /proc/module_hide+ | |
| # /proc/module_hide- | |
| # /proc/givemeinfo | |
| # Xzibit Rootkit (also see MRK (MiCrobul?) RootKit) | |
| XZIBIT_FILES="/dev/dsx | |
| /dev/caca | |
| /dev/ida/.inet/linsniffer | |
| /dev/ida/.inet/logclear | |
| /dev/ida/.inet/sense | |
| /dev/ida/.inet/sl2 | |
| /dev/ida/.inet/sshdu | |
| /dev/ida/.inet/s | |
| /dev/ida/.inet/ssh_host_key | |
| /dev/ida/.inet/ssh_random_seed | |
| /dev/ida/.inet/sl2new.c | |
| /dev/ida/.inet/tcp.log | |
| /home/httpd/cgi-bin/becys.cgi | |
| /usr/local/httpd/cgi-bin/becys.cgi | |
| /usr/local/apache/cgi-bin/becys.cgi | |
| /www/httpd/cgi-bin/becys.cgi | |
| /www/cgi-bin/becys.cgi" | |
| XZIBIT_DIRS="/dev/ida/.inet" | |
| XZIBIT_KSYMS= | |
| # X-Org SunOS Rootkit | |
| XORGSUNOS_FILES="/usr/lib/libX.a/bin/tmpfl | |
| /usr/lib/libX.a/bin/rps | |
| /usr/bin/srload | |
| /usr/lib/libX.a/bin/sparcv7/rps | |
| /usr/sbin/modcheck" | |
| XORGSUNOS_DIRS="/usr/lib/libX.a | |
| /usr/lib/libX.a/bin | |
| /usr/lib/libX.a/bin/sparcv7 | |
| /usr/share/man..." | |
| XORGSUNOS_KSYMS= | |
| # zaRwT.KiT Rootkit | |
| ZARWT_FILES="/dev/rd/s/sendmeil | |
| /dev/ttyf | |
| /dev/ttyp | |
| /dev/ttyn | |
| /rk/tulz" | |
| ZARWT_DIRS="/rk | |
| /dev/rd/s" | |
| ZARWT_KSYMS= | |
| # ZK Rootkit | |
| ZK_FILES="/usr/share/.zk/zk | |
| /usr/X11R6/.zk/xfs | |
| /usr/X11R6/.zk/echo | |
| /etc/1ssue.net | |
| /etc/sysconfig/console/load.zk" | |
| ZK_DIRS="/usr/share/.zk | |
| /usr/X11R6/.zk" | |
| ZK_KSYMS= | |
| # Miscellaneous login backdoors | |
| LOGIN_BACKDOOR_FILES="/bin/.login | |
| /sbin/.login" | |
| # Suspicious directories | |
| SUSPICIOUS_DIRS="/usr/X11R6/bin/.,/copy | |
| /dev/rd/cdb" | |
| # Evil strings | |
| STRINGSCAN="crond:LOGNAME=root:Illogic Rootkit | |
| hostname:phalanx:Phalanx Rootkit | |
| init:/dev/proc/fuckit:Fuckit Rootkit | |
| init:FUCK:Suckit Rootkit | |
| init:backdoor:Suckit Rootkit (backdoored init file) | |
| init:/usr/bin/rcpc:Portacelo Rootkit | |
| init:/usr/sbin/login:trNkit Rootkit ulogin | |
| killall:/dev/ptyxx/.proc:Ambient (ark) Rootkit | |
| login:vt200:Linux Rootkit (LRK4) | |
| login:/usr/bin/xstat:Linux Rootkit (LRK4) | |
| login:/bin/envpc:Linux Rootkit (LRK4) | |
| login:L4m3r0x:Linux Rootkit (LRK4) | |
| login:/lib/libext:SHV4 Rootkit | |
| login:/usr/sbin/login:Flea Linux Rootkit | |
| login:/usr/lib/.tbd:TBD Rootkit | |
| login:sendmail:Ambient (ark) Rootkit | |
| login:cocacola:cb Rootkit | |
| login:joao:Spanish Rootkit | |
| ls:/dev/ptyxx/.file:Dica-Kit Rootkit | |
| ls:/dev/ptyxx/.file:Ambient (ark) Rootkit | |
| ls:/dev/sgk:Linux Rootkit (LRK4) | |
| ls:/var/lock/subsys/...datafile...:Ohhara Rootkit | |
| ls:/usr/lib/.tbd:TBD Rootkit | |
| netstat:/dev/proc/fuckit:Fuckit Rootkit | |
| netstat:/lib/.sso:Dica-Kit Rootkit | |
| netstat:/var/lock/subsys/...datafile...:Ohhara Rootkit | |
| netstat:/dev/caca:MRK Rootkit | |
| netstat:/dev/ttyoa:Sin Rootkit | |
| netstat:/usr/lib/ldlibns.so:Flea Linux Rootkit | |
| netstat:/dev/ptyxx/.addr:Ambient (ark) Rootkit | |
| netstat:syg:Trojaned netstat | |
| nscd:sshd_config:Backdoor shell installed (SSH) | |
| ps:/var/lock/subsys/...datafile...:Ohhara Rootkit or Ni0 Rootkit | |
| ps:/dev/pts/01:Universal Rootkit (URK) | |
| ps:tw33dl3:SunOS Rootkit | |
| ps:psniff:SunOS Rootkit | |
| ps:uconf.inv:Universal Rootkit (URK) | |
| ps:lib/ldlibps.so:Flea Linux Rootkit or Universal Rootkit (URK) | |
| pstree:/usr/lib/ldlibpst.so:Flea Linux Rootkit | |
| ps:libproc.so.2.0.7:Fuckit Rootkit | |
| ps:/dev/ptyxx/.proc:Ambient (ark) Rootkit | |
| pstree:/dev/ptyxx/.proc:Ambient (ark) Rootkit | |
| pgrep:libproc.so.2.0.7:Fuckit Rootkit | |
| pkill:libproc.so.2.0.7:Fuckit Rootkit | |
| ping:/bin/bash:Ping Rootkit or other backdoor | |
| rpc.nfsd:cant open log:Sniffer installed | |
| rpc.nfsd:sniff.pid:Sniffer installed | |
| rpc.nfsd:tcp.log:Sniffer installed | |
| sshd:/dev/ptyxx:OpenBSD Rootkit | |
| sshd:/.config:SHV4 Rootkit | |
| sshd:+\\$.*\\$!.*!!\\$:Backdoored SSH daemon installed | |
| sshd:backdoor.h:Trojaned SSH daemon | |
| sshd:backdoor_active:Trojaned SSH daemon | |
| sshd:magic_pass_active:Trojaned SSH daemon | |
| sshd:/usr/include/gpm2.h:Trojaned SSH daemon | |
| sshd:/usr/include/openssl:Trojaned SSH daemon | |
| sshd:aion:Trojaned SSH daemon | |
| sshd:pcszPass:Trojaned SSH daemon | |
| sshd:LogPass:Trojaned SSH daemon | |
| sshd:Login_Check:Trojaned SSH daemon | |
| sshd:includes.h:Trojaned SSH daemon | |
| sshd:DecodeString:Trojaned SSH daemon | |
| sshd:EncodeString:Trojaned SSH daemon | |
| sshd:libns2.so:Ebury sshd backdoor | |
| sshd:libns5.so:Ebury sshd backdoor | |
| sshd:libpw3.so:Ebury sshd backdoor | |
| sshd:libpw5.so:Ebury sshd backdoor | |
| sshd:libsbr.so:Ebury sshd backdoor | |
| sshd:libslr.so:Ebury sshd backdoor | |
| xntps:/.config:SHV4 Rootkit | |
| syslogd:promiscuous:Sniffer installed | |
| syslogd:/usr/lib/.tbd:TBD Rootkit | |
| syslogd:/dev/ptyxx/.log:Ambient (ark) Rootkit | |
| syslogd:/usr/share/pci.r:Trojaned Syslog daemon | |
| tcpd:/dev/xdta:Dica-Kit Rootkit | |
| top:/usr/lib/.tbd:TBD Rootkit | |
| top:/dev/ptyxx/.proc:Ambient (ark) Rootkit | |
| xtty:/bin/sh:Backdoor shell | |
| ttymon:fucknut:SHV5 Rootkit | |
| ttymon:lamersucks:SHV5 Rootkit | |
| ttymon:skillz:SHV5 Rootkit | |
| ttyload:/sbin/ttyload:SHV5 Rootkit | |
| ttyload:/sbin/ttymon:SHV5 Rootkit | |
| ttyload:propert of SH:SHV5 Rootkit | |
| rcfile:in.inetd:SHV4 Rootkit | |
| rcfile:+#<HIDE_.*>:Enye LKM | |
| rcfile:bin/xchk:Optic Kit (Tux) Worm | |
| rcfile:bin/xsf:Optic Kit (Tux) Worm | |
| rcfile:/usr/bin/ssh2d:Flea Linux Rootkit or Optic Kit (Tux variant) Rootkit or SunOS Rootkit | |
| rcfile:/usr/sbin/xntps:SHV4 Rootkit | |
| rcfile:ttyload:SHV5 Rootkit | |
| rcfile:/etc/rc.d/init.d/init:cb Rootkit or w00tkit Rootkit | |
| rcfile:usr/bin/xfss:Devil Rootkit | |
| rcfile:/usr/sbin/rpc.netinet:FreeBSD (FBRK) Rootkit | |
| rcfile:/usr/lib/.fx/cons.saver:FreeBSD (FBRK) Rootkit | |
| rcfile:/usr/lib/.fx/xs:FreeBSD (FBRK) Rootkit | |
| rcfile:/ssh2d:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/dev/kmod:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/crth.o:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/crtz.o:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/dev/dos:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/lpq:Illogic Rootkit or SunOS Rootkit | |
| rcfile:/usr/sbin/rescue:Spanish Rootkit | |
| rcfile:/usr/lib/lpstart:SunOS NSDAP Rootkit or Universal Rootkit (URK) | |
| rcfile:/volc:Volc Rootkit | |
| rcfile:sourcemask:Rootkit component | |
| rcfile:/bin/vobiscum:Rootkit component | |
| rcfile:/usr/sbin/in.telnet:Rootkit component | |
| rcfile:/usr/bin/hdparm?-t1?-X53?-p:Xzibit Rootkit | |
| rcfile:/lib/.xsyslog:Flooder (Linux/Bckdr-RKC) component | |
| rcfile:/etc/.xsyslog:Flooder (Linux/Bckdr-RKC) component | |
| rcfile:/lib/.ssyslog:Flooder (Linux/Bckdr-RKC) component | |
| rcfile:/tmp/.sendmail:Flooder (Linux/Bckdr-RKC) component | |
| rcfile:IptabLex:malware component | |
| rcfile:IptabLes:malware component | |
| ssh:/lib/ldd.so/tkps:SHV4 Rootkit | |
| ssh1:/lib/ldd.so/tkps:SHV4 Rootkit | |
| ssh:t0rnkit:T0rn Rootkit | |
| ssh:/dev/proc/fuckit:Fuckit Rootkit | |
| ssh:backdoor.h:Trojaned SSH daemon | |
| ssh:backdoor_active:Trojaned SSH daemon | |
| ssh:magic_pass_active:Trojaned SSH daemon | |
| ssh:/usr/include/gpm2.h:Trojaned SSH daemon | |
| skill:libproc.so.2.0.7:Fuckit Rootkit | |
| snice:libproc.so.2.0.7:Fuckit Rootkit | |
| top:libproc.so.2.0.7:Fuckit Rootkit | |
| slocate:/usr/lib/ldlibct.so:Flea Linux Rootkit | |
| locate:/usr/lib/ldlibct.so:Flea Linux Rootkit | |
| du:/usr/lib/ldlibdu.so:Flea Linux Rootkit | |
| du:/dev/ptyxx/.file:Ambient (ark) Rootkit | |
| w:libproc.so.2.0.7:Fuckit Rootkit | |
| xlogin:/lib/libext:SHV4 Rootkit | |
| hdparm:/dev/ida/.inet:Xzibit Rootkit | |
| pgrep:/usr/include/mysql/mysql.hh1:Rootkit component | |
| pkill:/usr/include/mysql/mysql.hh1:Rootkit component | |
| pmap:/usr/include/mysql/mysql.hh1:Rootkit component | |
| ps:/usr/include/mysql/mysql.hh1:Rootkit component | |
| w:/usr/include/mysql/mysql.hh1:Rootkit component | |
| top:/usr/include/mysql/mysql.hh1:Rootkit component | |
| bc:backconnect:Jynx Rootkit | |
| bc:magic?packet?received:Jynx Rootkit" | |
| # Possible rootkit files and directories | |
| # The '%' character represents a space. | |
| FILESCAN="file:/dev/sdr0:T0rn Rootkit MD5 hash database | |
| file:/dev/pisu:Rootkit component | |
| file:/dev/xdta:Dica-Kit Rootkit | |
| file:/dev/saux:Trojaned SSH daemon sniffer log | |
| file:/dev/hdx:Linux.RST.B infection | |
| file:/dev/hdx1:Linux.RST.B infection | |
| file:/dev/hdx2:Linux.RST.B infection | |
| file:/dev/ptyy:Rootkit component | |
| file:/dev/ptyu:Rootkit component | |
| file:/dev/ptyv:Rootkit component | |
| file:/dev/hdbb:Rootkit component | |
| file:/tmp/.syshackfile:Trojaned syslog daemon | |
| file:/tmp/.bash_history:Lite5-r Rootkit | |
| file:/usr/info/.clib:Backdoor component | |
| file:/usr/sbin/tcp.log:Sniffer log | |
| file:/usr/bin/take/pid:Trojaned SSH daemon | |
| file:/sbin/create:MzOzD Local backdoor | |
| file:/dev/ttypz:spwn login backdoor | |
| file:/var/log/tcp.log:beX2 Rootkit | |
| file:/usr/include/audit.h:beX2 Rootkit | |
| file:/usr/bin/sourcemask:Rootkit component | |
| file:/usr/bin/ras2xm:Rootkit component | |
| file:/dev/xmx:Dica-Kit Rootkit | |
| file:/usr/sbin/gpm.root:Rootkit component | |
| file:/bin/vobiscum:Rootkit component | |
| file:/bin/psr:Rootkit component | |
| file:/dev/kdx:Rootkit component | |
| file:/dev/dkx:Rootkit component | |
| file:/usr/sbin/sshd3:Rootkit component | |
| file:/usr/sbin/jcd:Rootkit component | |
| file:/usr/sbin/atd2:Rootkit component | |
| file:/home/httpd/cgi-bin/linux.cgi:Dica-Kit Rootkit | |
| file:/home/httpd/cgi-bin/psid:Dica-Kit Rootkit | |
| file:/home/httpd/cgi-bin/void.cgi:Dica-Kit Rootkit | |
| file:/etc/rc.d/init.d/system:Rootkit component | |
| file:/etc/rc.d/rc3.d/S93users:Rootkit component | |
| file:/tmp/.ush:Dica-Kit Rootkit | |
| file:/usr/lib/libhidefile.so:HIDEFILE envvar file-hiding library | |
| file:/etc/cron.d/kmod:Illogic Rootkit | |
| file:/usr/lib/dmis/dmisd:Trojaned SSH daemon | |
| file:/lib/secure/libhij.so:Solaris Trojaned SSH daemon | |
| file:/usr/sbin/sshd3:Rootkit component | |
| file:/etc/rc.d/init.d/crontab:Rootkit component | |
| file:/etc/rc.d/init.d/jcd:Rootkit component | |
| file:/usr/sbin/atd2:Rootkit component | |
| file:/etc/rc.d/rc5.d/S93users:Rootkit component | |
| file:/usr/include/mysql/mysql.hh1:Rootkit component | |
| file:/etc/init.d/xfs3:Rootkit component | |
| file:/usr/sbin/t.txt:Opyum kit component | |
| file:/usr/sbin/change:Opyum kit component | |
| file:/usr/sbin/s:Opyum kit component | |
| file:/bin/f:Opyum kit component | |
| file:/bin/i:Opyum kit component | |
| file:/lib/libncom.so.4.0.1:ncom rootkit library | |
| file:/sbin/zinit:Rootkit component | |
| file:/tmp/pass_ssh.log:Trojaned SSH daemon | |
| file:/usr/include/gpm2.h:Trojaned SSH daemon | |
| file:/etc/ssh/.sshd_auth:Trojaned SSH daemon (logins) | |
| file:/usr/lib/.sshd.h:Trojaned SSH daemon (logins) | |
| file:/var/run/.defunct:Trojaned SSH daemon | |
| file:/etc/httpd/run/.defunct:Trojaned SSH daemon | |
| file:/usr/share/pci.r:Trojaned Syslog daemon | |
| file:/etc/cron.daily/dnsquery:Sniffer | |
| file:/usr/lib/libutil1.2.1.2.so:Trojaned SSH daemon component (hwclock binary) | |
| file:/usr/lib/libppopen.so:Trojaned SSH daemon component | |
| file:/usr/include/libutil2.1.h:Trojaned SSH daemon component | |
| file:/usr/bin/munchhausen:Trojaned SSH daemon component | |
| file:/bin/ceva:Trojaned SSH daemon (client binary) | |
| file:/sbin/syslogd%:Trojaned SSH daemon (sebd) | |
| file:/usr/include/shup.h:Trojaned SSH daemon (client binary) | |
| file:/etc/rpm/sshdOLD:Trojaned SSH daemon (original sshd binary) | |
| file:/etc/rpm/sshOLD:Trojaned SSH daemon (original ssh binary) | |
| file:/usr/share/passwd.h:Trojaned SSH daemon (default configuration) | |
| file:/lib/.xsyslog:Flooder (Linux/Bckdr-RKC) component | |
| file:/etc/.xsyslog:Flooder (Linux/Bckdr-RKC) component | |
| file:/lib/.ssyslog:Flooder (Linux/Bckdr-RKC) component | |
| file:/tmp/.sendmail:Flooder (Linux/Bckdr-RKC) component | |
| file:/usr/share/sshd.sync:Trojaned SSH daemon | |
| file:/bin/zcut:Trojaned SSH daemon | |
| file:/usr/bin/zmuie:Trojaned SSH daemon | |
| file:/lib/libkeyutils.so.1.9:Sniffer component | |
| file:/lib64/libkeyutils.so.1.9:Sniffer component | |
| file:/usr/lib/libkeyutils.so.1.9:Sniffer component | |
| file:/usr/lib64/libkeyutils.so.1.9:Sniffer component | |
| file:/IptabLes:malware component | |
| file:/.IptabLex:malware component | |
| file:/boot/.IptabLex:malware component | |
| file:/boot/.IptabLes:malware component | |
| file:/boot/IptabLes:malware component | |
| file:/tmp/IptabLes:malware component | |
| file:/etc/rc.d/init.d/IptabLex:malware component | |
| file:/etc/rc.d/init.d/IptabLes:malware component | |
| file:/etc/rc.d/rc0.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc1.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc2.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc3.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc4.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc5.d/S55IptabLex:malware component | |
| file:/etc/rc.d/rc6.d/S55IptabLex:malware component | |
| file:/var/lib/update-rc.d/IptabLex:malware component | |
| file:/delallmykkk:malware component | |
| file:/usr/.IptabLes:malware component | |
| file:/usr/IptabLes:malware component | |
| file:/tmp/.flush:malware component | |
| file:/var/log/.flush:malware component | |
| file:/usr/.flush:malware component | |
| file:/etc/init.d/bluetoothdaemon:malware component | |
| file:/usr/bin/btdaemon:malware component | |
| file:/etc/rc1.d/S90bluetooth:malware component | |
| file:/etc/rc2.d/S90bluetooth:malware component | |
| file:/etc/rc3.d/S90bluetooth:malware component | |
| file:/etc/rc4.d/S90bluetooth:malware component | |
| file:/etc/rc5.d/S90bluetooth:malware component | |
| file:/etc/rc6.d/S90bluetooth:malware component | |
| file:/boot/pro:BillGates botnet component | |
| file:/boot/proh:BillGates botnet component | |
| file:/etc/atdd:BillGates botnet component | |
| file:/etc/atddd:BillGates botnet component | |
| file:/etc/cupsdd:BillGates botnet component | |
| file:/etc/cupsddd:BillGates botnet component | |
| file:/etc/cupsddh:BillGates botnet component | |
| file:/etc/dsfrefr:BillGates botnet component | |
| file:/etc/fdsfsfvff:BillGates botnet component | |
| file:/etc/ferwfrre:BillGates botnet component | |
| file:/etc/fwke.cfg:BillGates botnet component | |
| file:/etc/gdmorpen:BillGates botnet component | |
| file:/etc/gfhddsfew:BillGates botnet component | |
| file:/etc/gfhjrtfyhuf:BillGates botnet component | |
| file:/etc/ksapd:BillGates botnet component | |
| file:/etc/ksapdd:BillGates botnet component | |
| file:/etc/kysapd:BillGates botnet component | |
| file:/etc/kysapdd:BillGates botnet component | |
| file:/etc/rewgtf3er4t:BillGates botnet component | |
| file:/etc/sdmfdsfhjfe:BillGates botnet component | |
| file:/etc/sfewfesfs:BillGates botnet component | |
| file:/etc/sfewfesfsh:BillGates botnet component | |
| file:/etc/sksapd:BillGates botnet component | |
| file:/etc/sksapdd:BillGates botnet component | |
| file:/etc/skysapd:BillGates botnet component | |
| file:/etc/skysapdd:BillGates botnet component | |
| file:/etc/smarvtd:BillGates botnet component | |
| file:/etc/whitptabil:BillGates botnet component | |
| file:/etc/xfsdx:BillGates botnet component | |
| file:/etc/xfsdxd:BillGates botnet component | |
| file:/tmp/bill.lock:BillGates botnet component | |
| file:/tmp/gates.lock:BillGates botnet component | |
| file:/tmp/gates.lod:BillGates botnet component | |
| file:/tmp/moni.lock:BillGates botnet component | |
| file:/tmp/moni.lod:BillGates botnet component | |
| file:/tmp/notify.file:BillGates botnet component | |
| file:/usr/bin/.sshd:BillGates botnet component | |
| file:/usr/bin/bsd-port/getty:BillGates botnet component | |
| file:/usr/bin/bsd-port/getty.lock:BillGates botnet component | |
| file:/usr/bin/bsd-port/udevd.lock:BillGates botnet component | |
| file:/usr/bin/pojie:BillGates botnet component | |
| file:/usr/lib/libamplify.so:BillGates botnet component | |
| file:/etc/init.d/DbSecuritySpt:BillGates botnet component | |
| file:/etc/rc.d/init.d/DbSecuritySpt:BillGates botnet component | |
| file:/etc/cron.hourly/gcc.sh:BillGates botnet component | |
| file:/root/2016ttfacai:BillGates botnet component | |
| file:/proc/rs_dev:xorddos component | |
| file:/var/run/sftp.pid:xorddos component | |
| file:/var/run/udev.pid:xorddos component | |
| file:/var/run/mount.pid:xorddos component | |
| file:/etc/cron.hourly/cron.sh:xorddos component | |
| file:/etc/cron.hourly/udev.sh:xorddos component | |
| file:/etc/cron.hourly/udev.sh:xorddos component | |
| file:/lib/libgcc.so:xorddos component | |
| file:/lib/libgcc.so.bak:xorddos component | |
| file:/lib/libgcc4.so:xorddos component | |
| file:/lib/libgcc4.4.so:xorddos component | |
| file:/lib/udev/udev:xorddos component | |
| file:/lib/udev/debug:xorddos component | |
| dir:/dev/ptyas:Langsuir installation directory | |
| dir:/usr/bin/take:Trojaned SSH daemon | |
| dir:/usr/src/.lib:Rootkit component | |
| dir:/usr/share/man/man1/.1c:Eggdrop (IRC bot) | |
| dir:/lib/lblip.tk:T0rn Rootkit directory with backdoored SSH-configuration | |
| dir:/usr/sbin/...:Rootkit component | |
| dir:/usr/share/.gun:Rootkit component | |
| dir:/unde/vrei/tu/sa/te/ascunzi/in/server:Unknown rootkit | |
| dir:/usr/man/man1/..%%/.dir:Unknown rootkit | |
| dir:/usr/X11R6/include/X11/...:Unknown rootkit | |
| dir:/usr/X11R6/lib/X11/.fonts/misc/...:Unknown rootkit | |
| dir:/tmp/.sys:Rootkit component | |
| dir:/tmp/':Rootkit component | |
| dir:/tmp/.,:Rootkit component | |
| dir:/tmp/,.,:Rootkit component | |
| dir:/dev/shm/emilien:Rootkit component | |
| dir:/var/tmp/.log:Rootkit component | |
| dir:/tmp/zmeu/...%:Rootkit component | |
| dir:/var/log/ssh:Rootkit component | |
| dir:/dev/ida:Rootkit component | |
| dir:/var/lib/games/.src/ssk/shit:Rootkit component | |
| dir:/usr/lib/libshtift:Rootkit component | |
| dir:/usr/src/.poop:Ramen worm | |
| dir:/dev/wd4:IRC bot | |
| dir:/var/run/.tmp:Rootkit component | |
| dir:/usr/man/man1/lib/.lib:Rootkit component | |
| dir:/dev/portd:Rootkit component | |
| dir:/dev/...:Rootkit component | |
| dir:/usr/share/man/mansps:Rootkit component | |
| dir:/lib/.so:Rootkit component | |
| dir:/lib/.sso:Rootkit component | |
| dir:/usr/include/sslv3:Rootkit component | |
| dir:/dev/shm/sshd:Trojaned SSH daemon | |
| dir:/usr/share/locale/mk/.dev/sk:Sniffer | |
| dir:/usr/share/locale/mk/.dev:Sniffer | |
| dir:/usr/include/netda.h:Trojaned SSH daemon | |
| dir:/usr/include/.ssh:Trojaned SSH daemon | |
| dir:/usr/share/locale/jp/.%:IRC bot | |
| dir:/usr/share/.sqe:IRC bot" | |
| # Evil strings for FreeBSD KLD (Dynamic Kernel Linker modules) | |
| KLDSTATKEYWORDS="backd00r backdoor darkside nekit rpldev rpldev_mod spapem_core spapem_genr00t hide_process turtle" | |
| # Suspicious startup file strings | |
| RCLOCAL_STRINGS="/usr/bin/rpc.wall:Linux Rootkit (LRK4) | |
| sshdd:GasKit Rootkit | |
| hidef:Knark Rootkit | |
| /usr/bin/.etc:Dica-Kit Rootkit" | |
| # Suspicious open files | |
| # If the file information field starts with 'OSX ' then | |
| # it will only be tested for on OSX systems. | |
| SUSP_FILES_INFO="backdoor:Generic backdoor | |
| adore.o:Adore kernel module | |
| mod_rootme.so:Apache mod_rootme backdoor | |
| phide_mod.o:Process hiding kernel module | |
| lbk.ko:LBK FreeBSD kernel module | |
| vlogger.o:THC-Vlogger kernel module | |
| cleaner.o:Adore kernel module | |
| cleaner:Adore Rootkit | |
| ava:Adore Rootkit | |
| tzava:Adore Rootkit | |
| mod_klgr.o:klgr, keyboard logger (kernel module) | |
| hydra:THC-Hydra (password capture) | |
| hydra.restore:THC-Hydra (password capture) | |
| ras2xm:Unknown rootkit | |
| vobiscum:Unknown rootkit | |
| sshd3:Unknown rootkit | |
| system:Unknown rootkit | |
| t0rnsb:T0rn Rootkit | |
| t0rns:T0rn Rootkit | |
| t0rnp:T0rn Rootkit | |
| rx4u:Unknown rootkit | |
| rx2me:Unknown rootkit | |
| sshdu:Unknown rootkit | |
| glotzer:Unknown rootkit | |
| holber:Devil Rootkit | |
| xhide:Process hiding software | |
| xh:Process hiding software (alternative of XHide) | |
| emech:IRC bot | |
| psybnc:IRC bot | |
| mech:IRC bot | |
| httpd.bin:IRC bot | |
| mh:Dica-Kit Rootkit IRC bot | |
| xl:Dica-Kit Rootkit | |
| write:Dica-Kit Rootkit | |
| Phantasmagoria.o:Process hiding Linux kernel module | |
| lkt.o:Portacelo Rootkit | |
| nlkt.o:Portacelo Rootkit | |
| ld_poison.so:Jynx Rootkit | |
| .xsyslog:Flooder (Linux/Bckdr-RKC) component | |
| .ssyslog:Flooder (Linux/Bckdr-RKC) component | |
| pscan2:Port scanner | |
| scanssh:Port scanner | |
| sshf:Possible port scanner | |
| ssh-scan:Port scanner | |
| atac:Port scanner component | |
| \[pdflush\]:IRC bot | |
| libkeyutils.so.1.9:Spam tool component | |
| .IptabLex:malware component | |
| .IptabLes:malware component | |
| .flush:malware component | |
| \[bluetooth\]:malware component | |
| \[flush:malware component | |
| jynx2.so:Jynx2 Rootkit | |
| reality.so:Jynx2 Rootkit | |
| kernel_service:OSX KeRanger ransomware | |
| icloudsyncd:OSX Keydnap backdoor | |
| icloudproc:OSX Keydnap backdoor | |
| dbd:OSX Eleanor backdoor | |
| check_hostname:OSX Eleanor backdoor | |
| profiled:Mokes backdoor | |
| DropboxCache:Mokes backdoor | |
| storeuserd:OSX Mokes backdoor | |
| updateragent:OSX Proton backdoor" | |
| # System startup file pathnames | |
| RCLOCATIONS="/etc/rc.d | |
| /etc/rc.local | |
| /usr/local/etc/rc.d | |
| /usr/local/etc/rc.local | |
| /etc/conf.d/local.start | |
| /etc/init.d | |
| /etc/inittab | |
| /etc/systemd/system" | |
| # Integrity tests | |
| STRINGS_INTEGRITY="${BOBKIT_FILES} ${BOBKIT_DIRS} ${CINIK_FILES} | |
| ${CINIK_DIRS} ${DICA_FILES} ${FREEBSD_RK_FILES} | |
| ${TBD_FILES} ${TORN_FILES} ${TORN_DIRS}" | |
| SNIFFER_FILES="/usr/lib/libice.log | |
| /dev/prom/sn.l | |
| /dev/fd/.88/zxsniff.log" | |
| # Known bad Linux kernel modules | |
| LKM_BADNAMES="adore.o | |
| bkit-adore.o | |
| cleaner.o | |
| flkm.o | |
| knark.o | |
| modhide.o | |
| mod_klgr.o | |
| phide_mod.o | |
| vlogger.o | |
| p2.ko | |
| rpldev.o | |
| xC.o | |
| strings.o | |
| wkmr26.ko | |
| diamorphine.ko" | |
| return | |
| } | |
| strings_check() { | |
| # | |
| # This function carries out the 'strings' command check. | |
| # It passes specific strings through the strings command to | |
| # see if they are missing. If so, then it can indicate that | |
| # the command has been modified to hide information. | |
| # | |
| if `check_test strings`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST strings | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 STRINGS_CHECK_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST strings | |
| fi | |
| return | |
| fi | |
| # | |
| # First check to see if we have a 'strings' command. | |
| # | |
| if [ -z "${STRINGS_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 STRINGS_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' strings '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'strings' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'strings' | |
| fi | |
| return | |
| fi | |
| STRINGSFAILED=0 | |
| for STRING in ${STRINGS_INTEGRITY}; do | |
| STRINGNAME=`echo "${STRING}" | sed -e 's/\./\\\./g'` | |
| STRING_SEEN=`echo "${STRING}" | ${STRINGS_CMD} -a | grep "${STRINGNAME}" | tr -d ' '` | |
| if [ -z "${STRING_SEEN}" ]; then | |
| STRINGSFAILED=1 | |
| display --to LOG --type WARNING --result WARNING --log-indent 2 STRINGS_SCANNING_BAD "${STRING}" | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result OK --log-indent 2 STRINGS_SCANNING_OK "${STRING}" | |
| fi | |
| done | |
| if [ $STRINGSFAILED -eq 0 ]; then | |
| RKHTMPVAR="SCREEN" | |
| test $VERBOSE_LOGGING -eq 0 && RKHTMPVAR="SCREEN+LOG" | |
| display --to "${RKHTMPVAR}" --type PLAIN --result OK --color GREEN --screen-indent 4 STRINGS_CHECK | |
| else | |
| display --to SCREEN --type PLAIN --result WARNING --color RED --screen-indent 4 STRINGS_CHECK | |
| fi | |
| return | |
| } | |
| shared_libs_check() { | |
| # | |
| # This function checks shared library loading problems. | |
| # It is part of do_system_commands_checks and should precede or run | |
| # just after strings_check if enabled. | |
| # | |
| # | |
| # Remarks: | |
| # Oracle-10.1.0.3 on RHEL3 needs /etc/libcwait.so, | |
| # F-PROT Antivirus for GNU/Linux needs f-prot.so, | |
| # AVAYA Labs "stack overflow protection" uses libsafe. | |
| # | |
| if `check_test shared_libs`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST shared_libs | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 SHARED_LIBS_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST shared_libs | |
| fi | |
| return | |
| fi | |
| # | |
| # First check for preloading exported variables. | |
| # | |
| VARFOUND="" | |
| for VARNAME in LD_PRELOAD LD_AOUT_PRELOAD LD_ELF_PRELOAD; do | |
| VARNAME_VALUE_ORIG=`eval echo "\\$${VARNAME}"` | |
| VARNAME_VALUE=`echo "${VARNAME_VALUE_ORIG}" | tr ':' ' '` | |
| FOUND=0 | |
| for FNAME in ${VARNAME_VALUE}; do | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${SHARED_LIB_WHITELIST}\" | grep \" ${FNAMEGREP} \"`" ]; then | |
| FOUND=1 | |
| else | |
| display --to LOG --type INFO SHARED_LIBS_PRELOAD_LIB_WLIST "${FNAME}" | |
| fi | |
| done | |
| if [ $FOUND -eq 1 ]; then | |
| VARFOUND="${VARFOUND} | |
| ${VARNAME}=\"${VARNAME_VALUE_ORIG}\"" | |
| fi | |
| done | |
| VARFOUND=`echo "${VARFOUND}" | sed -e '/^$/d'` | |
| if [ -z "${VARFOUND}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_VAR | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_VAR | |
| IFS=$IFSNL | |
| for FNAME in ${VARFOUND}; do | |
| display --to LOG --type WARNING SHARED_LIBS_PRELOAD_VAR_FOUND "${FNAME}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Next check for a preload file. | |
| # | |
| FOUND=0 | |
| PRELOAD_FILE="/etc/ld.so.preload" | |
| if [ -s "${PRELOAD_FILE}" ]; then | |
| RKHLIBLIST="" | |
| display --to LOG --type INFO SHARED_LIBS_PRELOAD_FILE_FOUND "${PRELOAD_FILE}" | |
| for FNAME in `grep -v '^#' "${PRELOAD_FILE}"`; do | |
| FOUND=1 | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${SHARED_LIB_WHITELIST}\" | grep \" ${FNAMEGREP} \"`" ]; then | |
| RKHLIBLIST="${RKHLIBLIST} ${FNAME}" | |
| else | |
| display --to LOG --type INFO SHARED_LIBS_PRELOAD_LIB_WLIST "${FNAME}" | |
| fi | |
| done | |
| if [ -n "${RKHLIBLIST}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_FILE | |
| for FNAME in ${RKHLIBLIST}; do | |
| display --to LOG --type WARNING SHARED_LIBS_PRELOAD_LIB_FOUND "${FNAME}" | |
| done | |
| elif [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_FILE | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WHITELISTED --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_FILE | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PRELOAD_FILE | |
| fi | |
| # | |
| # Finally we check the LD_LIBRARY_PATH. This check may be | |
| # disabled by the user if the 'ldd' command is not available. | |
| # | |
| if `check_test shared_libs_path`; then | |
| display --to LOG --type INFO --log-nl STARTING_TEST shared_libs_path | |
| if [ -n "${LDD_CMD}" ]; then | |
| if [ -n "${LD_LIBRARY_PATH}" ]; then | |
| LD_LIBR_FAILED=0 | |
| RKHTMPVAR_BIN="" | |
| LD_LIBRARY_PATH_SAVED="${LD_LIBRARY_PATH}" | |
| if [ -z "${MD5_CMD}" ]; then | |
| MD5_CMD=`find_cmd md5sum` | |
| test -z "${MD5_CMD}" && MD5_CMD=`find_cmd md5` | |
| fi | |
| LS_CMD=`find_cmd ls` | |
| for RKHTMPVAR in FIND PS STRINGS MD5 LS STAT; do | |
| RKHTMPVAR=`eval echo "\\$${RKHTMPVAR}_CMD"` | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | cut -d' ' -f1` | |
| RKHTMPVAR_BIN="${RKHTMPVAR_BIN} ${RKHTMPVAR}" | |
| done | |
| for RKHTMPVAR in ${RKHTMPVAR_BIN}; do | |
| LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}" | |
| export LD_LIBRARY_PATH | |
| RKHTMPVAR_WITH=`${LDD_CMD} ${RKHTMPVAR} | sed -e 's/(0x[0-9a-f]*)/0xHEX/' 2>&1` | |
| unset LD_LIBRARY_PATH | |
| RKHTMPVAR_WITHOUT=`${LDD_CMD} ${RKHTMPVAR} | sed -e 's/(0x[0-9a-f]*)/0xHEX/' 2>&1` | |
| if [ "${RKHTMPVAR_WITH}" != "${RKHTMPVAR_WITHOUT}" ]; then | |
| # | |
| # Testing one command should be "evidence" enough. | |
| # | |
| LD_LIBR_FAILED=1 | |
| break | |
| fi | |
| done | |
| # | |
| # Reset things to the way they were before. | |
| # | |
| LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}" | |
| export LD_LIBRARY_PATH | |
| if [ $LD_LIBR_FAILED -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PATH | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 SHARED_LIBS_PATH | |
| display --to LOG --type WARNING SHARED_LIBS_PATH_BAD "${LD_LIBRARY_PATH}" | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 --log-indent 2 SHARED_LIBS_PATH | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 --log-indent 2 SHARED_LIBS_PATH | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ldd '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ldd' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ldd' | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST shared_libs_path | |
| fi | |
| return | |
| } | |
| updt_rkhdat() { | |
| # | |
| # This function is part of the file properties check. It is | |
| # used to add and remove entries from the rkhunter.dat file. | |
| # | |
| get_temp_file "${RKHTMPDIR}/rkhunter.dat" | |
| RKHDAT_TMPFILE="${TEMPFILE}" | |
| get_temp_file "${RKHTMPDIR}/rkhunter.dat2" | |
| RKHDAT_TMPFILE2="${TEMPFILE}" | |
| touch "${RKHDAT_TMPFILE}" "${RKHDAT_TMPFILE2}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${RKHDAT_TMPFILE}" | |
| display --to LOG --type INFO CREATED_TEMP_FILE "${RKHDAT_TMPFILE2}" | |
| cp -f -p "${RKHDAT_FILE}" "${RKHDAT_TMPFILE}" | |
| IFS=$IFSNL | |
| OLDRKHENTRIES=`echo "${OLDRKHENTRIES}" | sed -e '/^$/d'` | |
| for FNAME in ${OLDRKHENTRIES}; do | |
| if [ $FMTVERSION -eq 0 ]; then | |
| FILENAME=`echo "${FNAME}" | cut -d: -f2` | |
| else | |
| RKH_CC=`echo "${FNAME}" | cut -d: -f2` | |
| RKH_CC2=`expr 3 + $RKH_CC` | |
| FILENAME=`echo "${FNAME}" | cut -d: -f3-$RKH_CC2` | |
| fi | |
| display --to LOG --type INFO RKHDAT_DEL_OLD_ENTRY "`name2text \"${FILENAME}\"`" | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's:/:\\\/:g'` | |
| sed -e "/^${FNAMEGREP}$/d" "${RKHDAT_TMPFILE}" >"${RKHDAT_TMPFILE2}" | |
| cp -f "${RKHDAT_TMPFILE2}" "${RKHDAT_TMPFILE}" | |
| done | |
| NEWRKHENTRIES=`echo "${NEWRKHENTRIES}" | sed -e '/^$/d'` | |
| for FNAME in ${NEWRKHENTRIES}; do | |
| if [ $FMTVERSION -eq 0 ]; then | |
| FILENAME=`echo "${FNAME}" | cut -d: -f2` | |
| else | |
| RKH_CC=`echo "${FNAME}" | cut -d: -f2` | |
| RKH_CC2=`expr 3 + $RKH_CC` | |
| FILENAME=`echo "${FNAME}" | cut -d: -f3-$RKH_CC2` | |
| fi | |
| display --to LOG --type INFO RKHDAT_ADD_NEW_ENTRY "`name2text \"${FILENAME}\"`" | |
| echo "${FNAME}" >>"${RKHDAT_TMPFILE}" | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Now put the new rkhunter.dat file in place. | |
| # | |
| cp -f -p "${RKHDAT_FILE}" "${RKHDAT_FILE}.old" >/dev/null 2>&1 | |
| cp -f "${RKHDAT_TMPFILE}" "${RKHDAT_FILE}" >/dev/null 2>&1 | |
| ERRCODE=$? | |
| if [ $ERRCODE -ne 0 ]; then | |
| RET_CODE=1 | |
| display --to LOG --type INFO CMD_ERROR "cp ${RKHDAT_TMPFILE} ${RKHDAT_FILE}" $ERRCODE | |
| display --to SCREEN+LOG --type WARNING PROPUPD_ERROR $ERRCODE | |
| else | |
| display --to LOG --type INFO PROPUPD_NEW_DAT_FILE "${DB_PATH}" | |
| fi | |
| chmod 600 "${RKHDAT_FILE}" >/dev/null 2>&1 | |
| rm -f "${RKHDAT_TMPFILE}" "${RKHDAT_TMPFILE2}" >/dev/null 2>&1 | |
| return | |
| } | |
| file_properties_check() { | |
| # | |
| # This function carries out a check of system command property | |
| # values checked against their previous value, which is stored | |
| # in the rkhunter.dat file. Other checks work on the current | |
| # file, and do not use any previously stored value (for example, | |
| # the immutable-bit check). | |
| # | |
| # | |
| # Each test will set the variable TEST_RESULT, and use it to | |
| # display the actual result. Typically a null string indicates | |
| # 'OK', and anything else is a 'Warning'. | |
| # | |
| TEST_RESULT="" | |
| NEWRKHENTRIES="" | |
| OLDRKHENTRIES="" | |
| WHITELIST_RESULT="" | |
| SKIP_ATTR=0; SKIP_HASH=0; SKIP_IMMUT=0; SKIP_SCRIPT=0 | |
| USE_DAT_FILE=1 | |
| SKIP_IMMUT_OS=0 | |
| PROP_FILE_LIST_COUNT=0 | |
| ADDNEWENTRY=0 | |
| # | |
| # In order to disable the whole test we have to check if | |
| # each specific test has been disabled. | |
| # | |
| for RKHTMPVAR in attributes hashes immutable scripts; do | |
| if ! `check_test ${RKHTMPVAR}`; then | |
| case "${RKHTMPVAR}" in | |
| attributes) | |
| SKIP_ATTR=1 | |
| ;; | |
| hashes) | |
| SKIP_HASH=1 | |
| ;; | |
| immutable) | |
| SKIP_IMMUT=1 | |
| ;; | |
| scripts) | |
| SKIP_SCRIPT=1 | |
| ;; | |
| esac | |
| fi | |
| done | |
| # | |
| # The immutable-bit test is only applicable to Linux and | |
| # BSD systems. We need to disable the test, but not have | |
| # it logged as if the user had disabled it (that would be | |
| # confusing). | |
| # | |
| if [ $BSDOS -eq 0 -a $LINUXOS -eq 0 ]; then | |
| if [ $SKIP_IMMUT -eq 0 ]; then | |
| SKIP_IMMUT=1 | |
| SKIP_IMMUT_OS=1 | |
| fi | |
| fi | |
| if ! `check_test properties`; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST properties | |
| fi | |
| return | |
| elif [ $SKIP_ATTR -eq 1 -a $SKIP_HASH -eq 1 -a $SKIP_IMMUT -eq 1 -a $SKIP_SCRIPT -eq 1 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST properties | |
| fi | |
| return | |
| else | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST properties | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 FILE_PROP_START | |
| fi | |
| # | |
| # If the user wants to skip a test then log it. | |
| # | |
| for RKHTMPVAR in attributes hashes immutable scripts; do | |
| case "${RKHTMPVAR}" in | |
| attributes) | |
| TEST_NAME=$SKIP_ATTR | |
| ;; | |
| hashes) | |
| TEST_NAME=$SKIP_HASH | |
| ;; | |
| scripts) | |
| TEST_NAME=$SKIP_SCRIPT | |
| ;; | |
| immutable) | |
| TEST_NAME=0 | |
| test $SKIP_IMMUT_OS -eq 0 && TEST_NAME=$SKIP_IMMUT | |
| ;; | |
| esac | |
| if [ $TEST_NAME -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO USER_DISABLED_TEST ${RKHTMPVAR} | |
| fi | |
| done | |
| # | |
| # The first test we do is on the commands needed to | |
| # perform all the file checks. If the user has not | |
| # disabled any test, and a command is missing, then | |
| # we must let them know that without marking each file | |
| # test as a 'Warning' (because that could hide a real | |
| # problem). We include checks on the rkhunter.dat file | |
| # as well. | |
| # | |
| RKHTMPVAR="" | |
| if [ $SKIP_ATTR -eq 0 -a -z "${STAT_CMD}" ]; then | |
| SKIP_ATTR=1 | |
| RKHTMPVAR="${RKHTMPVAR} attr" | |
| fi | |
| if [ $SKIP_HASH -eq 0 ]; then | |
| # Not sure about this one...! | |
| if [ -z "${OLD_PKGMGR}" -a -s ${RKHDAT_FILE} -a "${HASH_FUNC}" != "NONE" -a \( "${OLD_HASH_FUNC}" = "NONE" -o "${OLD_HASH_FUNC}" = "Disabled" -o -z "${OLD_HASH_FUNC}" \) ]; then | |
| SKIP_HASH=1 | |
| RKHTMPVAR="${RKHTMPVAR} hash" | |
| if [ -n "${PRELINK_HASH}" ]; then | |
| HASH_FUNC_ERR="prelink with ${PRELINK_HASH}" | |
| else | |
| HASH_FUNC_ERR="${HASH_FUNC}" | |
| fi | |
| if [ -z "${OLD_HASH_FUNC}" ]; then | |
| OLD_HASH_FUNC_ERR="Unset" | |
| elif [ "${OLD_HASH_FUNC}" = "MD5" -o "${OLD_HASH_FUNC}" = "SHA1" ]; then | |
| # Oops! This can't be reached. | |
| OLD_HASH_FUNC_ERR="prelink with ${OLD_HASH_FUNC}" | |
| else | |
| OLD_HASH_FUNC_ERR="${OLD_HASH_FUNC}" | |
| fi | |
| if [ -z "${PKGMGR}" ]; then | |
| PKGMGR_ERR="Unset" | |
| else | |
| PKGMGR_ERR="${PKGMGR}" | |
| fi | |
| if [ -z "${OLD_PKGMGR}" ]; then | |
| OLD_PKGMGR_ERR="Unset" | |
| else | |
| OLD_PKGMGR_ERR="${OLD_PKGMGR}" | |
| fi | |
| fi | |
| if [ $SKIP_HASH_MSG -eq 1 ]; then | |
| SKIP_HASH=1 | |
| RKHTMPVAR="${RKHTMPVAR} sha1" | |
| elif [ $SKIP_HASH_MSG -eq 2 ]; then | |
| SKIP_HASH=1 | |
| RKHTMPVAR="${RKHTMPVAR} libsafe" | |
| fi | |
| fi | |
| if [ $SKIP_IMMUT -eq 0 ]; then | |
| if [ $BSDOS -eq 1 ]; then | |
| for FNAME in ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES} ${DB_PATH}/*.dat ${DB_PATH}/i18n/*; do | |
| test -f "${FNAME}" -a ! -h "${FNAME}" && break | |
| done | |
| if [ -z "`ls -lno \"${FNAME}\" 2>/dev/null`" ]; then | |
| SKIP_IMMUT=1 | |
| RKHTMPVAR="${RKHTMPVAR} immutable-bsd" | |
| fi | |
| else | |
| if [ -z "${LSATTR_CMD}" ]; then | |
| SKIP_IMMUT=1 | |
| RKHTMPVAR="${RKHTMPVAR} immutable" | |
| else | |
| for FNAME in ${CONFIGFILE} ${LOCALCONFIGFILE} ${LOCALCONFDIRFILES} ${DB_PATH}/*.dat ${DB_PATH}/i18n/*; do | |
| test -f "${FNAME}" -a ! -h "${FNAME}" && break | |
| done | |
| if [ -z "`${LSATTR_CMD} \"${FNAME}\" 2>/dev/null`" ]; then | |
| SKIP_IMMUT=1 | |
| RKHTMPVAR="${RKHTMPVAR} immutable-cmd" | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ $SKIP_SCRIPT -eq 0 ]; then | |
| if [ -z "${FILE_CMD}" ]; then | |
| SKIP_SCRIPT=1 | |
| RKHTMPVAR="${RKHTMPVAR} script" | |
| elif [ -z "`${FILE_CMD} \"${CONFIGFILE}\" 2>/dev/null`" ]; then | |
| SKIP_SCRIPT=1 | |
| RKHTMPVAR="${RKHTMPVAR} script-cmd" | |
| fi | |
| fi | |
| if [ $SKIP_ATTR -eq 0 -o $SKIP_HASH -eq 0 ]; then | |
| if [ ! -f "${RKHDAT_FILE}" ]; then | |
| SKIP_HASH=1 | |
| SKIP_ATTR=1 | |
| USE_DAT_FILE=0 | |
| RKHTMPVAR="${RKHTMPVAR} missing" | |
| fi | |
| if [ $USE_DAT_FILE -eq 1 -a ! -s ${RKHDAT_FILE} ]; then | |
| SKIP_HASH=1 | |
| SKIP_ATTR=1 | |
| USE_DAT_FILE=0 | |
| RKHTMPVAR="${RKHTMPVAR} empty" | |
| fi | |
| else | |
| # | |
| # If we are not checking the file attributes or | |
| # the hash value, then we don't need to look at | |
| # the rkhunter.dat file. The other tests can be | |
| # done without the file. | |
| # | |
| USE_DAT_FILE=0 | |
| fi | |
| # | |
| # If the O/S has changed in some way, and we are not just reporting warnings, | |
| # and O/S warnings are enabled, then show a warning in the prerequisites test. | |
| # | |
| if [ $OS_CHANGED -eq 1 -a $SHOWWARNINGSONLY -eq 0 -a $WARN_ON_OS_CHANGE -eq 1 ]; then | |
| RKHTMPVAR="${RKHTMPVAR} os_changed" | |
| fi | |
| # | |
| # If all the previous checks have disabled all the tests, | |
| # then we tell the user and then return. | |
| # | |
| if [ $SKIP_ATTR -eq 1 -a $SKIP_HASH -eq 1 -a $SKIP_IMMUT -eq 1 -a $SKIP_SCRIPT -eq 1 ]; then | |
| RKHTMPVAR="${RKHTMPVAR} notests" | |
| fi | |
| # | |
| # Display the results. | |
| # | |
| if [ $SKIP_IMMUT_OS -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_IMMUT_OS | |
| fi | |
| if [ $IMMUTABLE_SET -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_IMMUT_SET | |
| fi | |
| if [ $SKIP_INODE_CHECK -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_SKIP_INODE | |
| fi | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 --log-indent 2 --result OK --color GREEN FILE_PROP_CMDS | |
| else | |
| SUMMARY_PROP_REQCMDS=1 | |
| display --to SCREEN+LOG --type WARNING --screen-indent 4 --log-indent 2 --result WARNING --color RED FILE_PROP_CMDS | |
| RKHTMPVAR2=0 | |
| for TEST_RESULT in ${RKHTMPVAR}; do | |
| case "${TEST_RESULT}" in | |
| attr) | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' stat '`" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_ATTR_DISABLED | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_ATTR | |
| fi | |
| ;; | |
| hash|prelink|sha1|libsafe) | |
| if [ $RKHTMPVAR2 -eq 0 ]; then | |
| RKHTMPVAR2=1 | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_HASH | |
| fi | |
| case "${TEST_RESULT}" in | |
| hash) | |
| display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_FUNC "${HASH_FUNC_ERR}" "${PKGMGR_ERR}" "${OLD_HASH_FUNC_ERR}" "${OLD_PKGMGR_ERR}" | |
| ;; | |
| prelink) | |
| display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_PRELINK | |
| ;; | |
| sha1) | |
| display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_SHA1 | |
| ;; | |
| libsafe) | |
| display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_LIBSAFE | |
| ;; | |
| esac | |
| ;; | |
| immutable) | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' lsattr '`" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_IMMUT_DISABLED | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_IMMUT | |
| fi | |
| ;; | |
| immutable-bsd) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_IMMUT_CMD 'ls -lno' | |
| ;; | |
| immutable-cmd) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_IMMUT_CMD 'lsattr' | |
| ;; | |
| script) | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' file '`" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_SCRIPT_DISABLED | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_SCRIPT | |
| fi | |
| ;; | |
| script-cmd) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_FILE_CMD | |
| ;; | |
| os_changed) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_OS_CHANGED | |
| ;; | |
| missing) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_DAT_MISSING | |
| display --to LOG --type INFO FILE_PROP_DAT_MISSING_INFO | |
| ;; | |
| empty) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_DAT_EMPTY | |
| display --to LOG --type INFO FILE_PROP_DAT_MISSING_INFO | |
| ;; | |
| esac | |
| done | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep -E 'libsafe|missing|empty'`" ]; then | |
| display --to LOG --type WARNING --nl PROPUPD_WARN | |
| fi | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep 'notests'`" ]; then | |
| display --to LOG --type WARNING --nl FILE_PROP_SKIP_ALL | |
| return | |
| fi | |
| fi | |
| # | |
| # Set up some local variables depending on what | |
| # commands we have available. | |
| # | |
| if [ $SKIP_ATTR -eq 1 ]; then | |
| SCMD="" | |
| INODECMD="" | |
| else | |
| if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then | |
| if [ "${PKGMGR}" = "SOLARIS" ]; then | |
| SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --mtime" | |
| else | |
| SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --Mtime" | |
| fi | |
| INODECMD="${STAT_CMD} --modeoct --raw --ino" | |
| elif [ $BSDOS -eq 1 -o $MACOSX -eq 1 ]; then | |
| SCMD="${STAT_CMD} -f '%i %Mp%Lp %u %g %z %m:'" | |
| INODECMD="${STAT_CMD} -f '%i'" | |
| else | |
| SCMD="${STAT_CMD} -c '%i 0%a %u %g %s %Y:'" | |
| INODECMD="${STAT_CMD} -c '%i'" | |
| fi | |
| fi | |
| if [ $SKIP_HASH -eq 1 ]; then | |
| SYSHASH="" | |
| HASH_CMD="" | |
| else | |
| HASH_CMD="${HASH_FUNC}" | |
| fi | |
| # | |
| # Next we have to recreate the list of pathnames for the | |
| # file properties checks. We need to recreate it because | |
| # the root PATH may have changed, and so there may be more | |
| # directories to be checked. However, if we have just run | |
| # the '--propupd' option, then we can skip this. | |
| # | |
| test $PROP_UPDATE -eq 0 && create_rkh_file_prop_list | |
| # | |
| # We need the current 'rkhunter.dat' file format. | |
| # | |
| if [ $USE_DAT_FILE -eq 1 ]; then | |
| FMTVERSION=`grep '^FormatVersion:' "${RKHDAT_FILE}" | cut -d: -f2` | |
| test -z "${FMTVERSION}" && FMTVERSION=0 | |
| else | |
| FMTVERSION=0 | |
| fi | |
| # | |
| # Now loop through each of the files and perform the tests on each one. | |
| # | |
| # We must set IFS around this loop, otherwise any names in the file | |
| # properties list containing whitespace will be separated out. | |
| # However, because IFS interacts with some commands, executed via | |
| # backticks, we must then reset IFS for the duration of the loop | |
| # and set it again at the end of the loop. It's messy, but it works. | |
| # | |
| IFS=$IFSNL | |
| VERIFIED_PKG_LIST="" | |
| for FNAME in `cat "${RKH_FILEPROP_LIST}"`; do | |
| SYSLNK="" | |
| FILENAME="" | |
| FNAMEGREP="" | |
| TEST_RESULT="" | |
| WHITELIST_RESULT="" | |
| RKH_CC=0 | |
| SYSLNK_CC=0 | |
| NOVRFYFILE=0 | |
| ADDNEWENTRY=0 | |
| COLON_COUNT=0 | |
| FILE_IS_PKGD=0 | |
| DEPENDENCY_ERR=0 | |
| HASH_TEST_PASSED=0 | |
| SIZE_TEST_PASSED=0 | |
| IFS=$RKHIFS | |
| # | |
| # We first need to test if the file exists or not, | |
| # and if the file is listed in the rkhunter.dat | |
| # file or not. This can indicate files that have | |
| # appeared on or disappeared from the system. | |
| # | |
| FNAME=`echo "${FNAME}" | sed -e 's/^"\(.*\)"$/\1/'` | |
| if [ -f "${FNAME}" -o -h "${FNAME}" ]; then | |
| FILE_EXISTS=1 | |
| PROP_FILE_LIST_COUNT=`expr ${PROP_FILE_LIST_COUNT} + 1` | |
| else | |
| FILE_EXISTS=0 | |
| fi | |
| if [ $USE_DAT_FILE -eq 1 ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHLINE=`grep "^File:${FNAMEGREP}:" "${RKHDAT_FILE}"` | |
| else | |
| COLON_COUNT=`echo "${FNAME}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| RKHLINE=`grep "^File:${COLON_COUNT}:${FNAMEGREP}:" "${RKHDAT_FILE}"` | |
| fi | |
| if [ $FILE_EXISTS -eq 1 -a -z "${RKHLINE}" ]; then | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| # | |
| # We need to add the file to the rkhunter.dat file. | |
| # We add a dummy entry to start with, but it must contain values. | |
| # | |
| ADDNEWENTRY=1 | |
| if [ -h "${FNAME}" -a $HAVE_READLINK -eq 1 ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHLINE="File:${FNAME}:1:1:1:1:1:1:1::${SYSLNK}:" | |
| else | |
| SYSLNK_CC=`echo "${SYSLNK}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| RKHLINE="File:${COLON_COUNT}:${FNAME}:1:1:1:1:1:1:1::${SYSLNK_CC}:${SYSLNK}:" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhline" | |
| fi | |
| elif [ $FILE_EXISTS -eq 0 ]; then | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ -n "${RKHLINE}" ]; then | |
| # | |
| # We need to remove the file from the rkhunter.dat file. | |
| # | |
| OLDRKHENTRIES="${OLDRKHENTRIES} | |
| ${RKHLINE}" | |
| fi | |
| elif [ -n "${RKHLINE}" ]; then | |
| PROP_FAILED_COUNT=`expr ${PROP_FAILED_COUNT} + 1` | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 --log-indent 2 --result WARNING --color RED NAME "`name2text \"${FNAME}\"`" | |
| display --to LOG --type WARNING FILE_PROP_FILE_NOT_EXIST "`name2text \"${FNAME}\"`" | |
| fi | |
| IFS=$IFSNL | |
| continue | |
| fi | |
| elif [ $FILE_EXISTS -eq 1 ]; then | |
| RKHLINE="" | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| else | |
| IFS=$IFSNL | |
| continue | |
| fi | |
| # | |
| # Start the tests. | |
| # | |
| SYSUID=0 | |
| SYSGID=0 | |
| SYSDTM=0 | |
| SYSSIZE=0 | |
| SYSPERM=0 | |
| SYSINODE=0 | |
| RKHLNK="" | |
| SYSHASH="" | |
| if [ $USE_DAT_FILE -eq 1 -a -n "${RKHLINE}" ]; then | |
| FDATA="" | |
| RPM_QUERY_RESULT="" | |
| PKGMGR_VERIFY_RESULT="" | |
| # | |
| # We need to calculate if the filename (in the file) has any colons in it. | |
| # We then set RKH_CC to point to the field after the filename (the hash field). | |
| # | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKH_CC=3 | |
| else | |
| RKH_CC=`echo "${RKHLINE}" | cut -d: -f2` | |
| RKH_CC=`expr 4 + $RKH_CC` | |
| fi | |
| # | |
| # See if the file is to be exempt from any package manager verification. | |
| # | |
| if [ -n "`echo \"${PKGMGRNOVRFY}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| NOVRFYFILE=1 | |
| fi | |
| # | |
| # Because the RPM package manager can verify most of the tests we are | |
| # doing, we obtain the verified data now. The Solaris package manager | |
| # provides some data, but does not verify it against the values on disk. | |
| # With all the package managers we have to obtain unverified data by | |
| # using commands. The other package managers, at present, only provide | |
| # the MD5 checksum. As such we simply handle them within the hash test. | |
| # | |
| if [ "${PKGMGR}" = "RPM" ]; then | |
| # | |
| # First we see if the file is exempt or part of a package. | |
| # | |
| if [ $NOVRFYFILE -eq 0 ]; then | |
| PKGNAME_ARCH=`${RPM_CMD} -qf "${FNAME}" --queryformat '%{N}-%{V}-%{R}.%{ARCH}\n' 2>/dev/null` | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # Okay we have a package name. Is it in the list | |
| # of packages we have already tested as verified? | |
| # | |
| # If multiple packages claim the same file, we use | |
| # 64-bit over 32-bit, or simply the last one. | |
| # | |
| FILE_IS_PKGD=1 | |
| PKGNAME=`echo "${PKGNAME_ARCH}" | grep -E '\.(x86_64|ia64)$' 2>/dev/null | tail ${TAIL_OPT}1` | |
| test -z "${PKGNAME}" && PKGNAME=`echo "${PKGNAME_ARCH}" | tail ${TAIL_OPT}1` | |
| RKHTMPVAR=`echo "${PKGNAME}" | sed -e 's/\./\\\./g'` | |
| if [ -z "`echo \"${VERIFIED_PKG_LIST}\" | grep \" ${RKHTMPVAR} \"`" ]; then | |
| # | |
| # No, it isn't in the list. So we verify the package | |
| # and either add it to the list if it verifies okay, | |
| # or get the verification result for the file. | |
| # | |
| PKGMGR_VERIFY_RESULT=`${RPM_CMD} -V "${PKGNAME}" 2>&1` | |
| if [ -z "${PKGMGR_VERIFY_RESULT}" ]; then | |
| VERIFIED_PKG_LIST="${VERIFIED_PKG_LIST} ${PKGNAME} " | |
| else | |
| if [ -n "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep \"prelink.* ${FNAME}.* dependenc\"`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| PKGMGR_VERIFY_RESULT=`echo "${PKGMGR_VERIFY_RESULT}" | grep " ${FNAMEGREP}\$" | cut -d' ' -f1` | |
| fi | |
| fi | |
| # | |
| # The package manager check does not verify all the items | |
| # we check. So we still need to dig out the rest of the | |
| # information about this file from the package manager database. | |
| # Note that the filenames are displayed at the end of the rpm output. | |
| # This means that any filename containing a colon will not cause | |
| # a problem. | |
| # | |
| RPM_QUERY_RESULT=`${RPM_CMD} -q --queryformat '[%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{FILELINKTOS}:%{FILENAMES}\n]' "${PKGNAME}" 2>/dev/null | grep ":${FNAMEGREP}\$"` | |
| ERRCODE=$? | |
| # | |
| # The error code actually refers to the 'grep' command above. If the | |
| # file is not found in the package, then this is probably due to the | |
| # 'bin' directory being a link. So we change the filename, and retest. | |
| # | |
| if [ $ERRCODE -eq 1 -a $BINISLINK -eq 1 ]; then | |
| if [ -n "`echo \"${FNAME}\" | grep '^\/usr\/'`" ]; then | |
| RKHTMPVAR3=`echo "${FNAMEGREP}" | sed -e 's:^/usr::'` | |
| else | |
| RKHTMPVAR3="/usr${FNAMEGREP}" | |
| fi | |
| RPM_QUERY_RESULT=`${RPM_CMD} -q --queryformat '[%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{FILELINKTOS}:%{FILENAMES}\n]' "${PKGNAME}" 2>/dev/null | grep ":${RKHTMPVAR3}\$"` | |
| ERRCODE=$? | |
| fi | |
| if [ $ERRCODE -eq 0 ]; then | |
| RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT}" | tail ${TAIL_OPT}1` | |
| FPERM="0`echo \"${RPM_QUERY_RESULT}\" | cut -d: -f1 | cut -c 3-`" | |
| FPERM=`echo "${FPERM}" | sed -e 's/^00/0/'` | |
| RKHUID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f2` | |
| RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3` | |
| RKHGID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f3` | |
| RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3` | |
| RKHSIZE=`echo "${RPM_QUERY_RESULT}" | cut -d: -f4` | |
| RKHDTM=`echo "${RPM_QUERY_RESULT}" | cut -d: -f5` | |
| if [ -h "${FNAME}" ]; then | |
| RKHLNK=`echo "${RPM_QUERY_RESULT}" | cut -d: -f7` | |
| if [ -z "`echo \"${RKHLNK}\" | grep '^/'`" ]; then | |
| test -n "${DIRNAME_CMD}" && DIR=`${DIRNAME_CMD} "${FNAME}"` || DIR=`echo "${FNAME}" | sed -e 's:/[^/]*$::'` | |
| RKHLNK="${DIR}/${RKHLNK}" | |
| fi | |
| # This ensures the link target has things like '..' removed. | |
| test $HAVE_READLINK -eq 1 && RKHLNK=`${READLINK_CMD} ${READLINK_OPT} "${RKHLNK}"` | |
| fi | |
| FDATA="${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}:" | |
| else | |
| # | |
| # If, for some reason, we cannot get the package information, | |
| # then treat it as if it returned all null values. | |
| # | |
| FDATA=":::::" | |
| display --to LOG --type INFO CMD_ERROR "rpm -qf --queryformat... \"${FNAME}\" (${PKGNAME})" $ERRCODE | |
| fi | |
| # | |
| # Now get the inode value directly from the disk, | |
| # but only if prelinking is not being used. | |
| # | |
| RKHTMPVAR="" | |
| if [ $PRELINKED -eq 0 -a -n "${INODECMD}" ]; then | |
| RKHTMPVAR=`eval ${INODECMD} "\"${FNAME}\"" 2>/dev/null | tr -d ' '` | |
| fi | |
| FDATA="${RKHTMPVAR}:${FDATA}" | |
| fi | |
| fi | |
| elif [ "${PKGMGR}" = "SOLARIS" ]; then | |
| # | |
| # First we see if the file is exempt or part of a package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| ERRCODE=1 | |
| else | |
| RKHTMPVAR=`grep "^${FNAMEGREP} " /var/sadm/install/contents 2>/dev/null` | |
| test -n "${RKHTMPVAR}" && ERRCODE=0 || ERRCODE=1 | |
| fi | |
| if [ $ERRCODE -eq 0 ]; then | |
| # | |
| # We will rebuild the RKHLINE value with the values from | |
| # the package manager database. We can then verify it just | |
| # as if it had been read from the RKH database. | |
| # | |
| FPERM=`echo "${RKHTMPVAR}" | cut -d' ' -f4` | |
| RKHUID=`echo "${RKHTMPVAR}" | cut -d' ' -f5` | |
| RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3` | |
| RKHGID=`echo "${RKHTMPVAR}" | cut -d' ' -f6` | |
| RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3` | |
| RKHSIZE=`echo "${RKHTMPVAR}" | cut -d' ' -f7` | |
| if [ $USE_SUNSUM -eq 1 ]; then | |
| # Treat this as a fully packaged file. | |
| FILE_IS_PKGD=1 | |
| RKHHASH=`echo "${RKHTMPVAR}" | cut -d' ' -f8` | |
| else | |
| RKHHASH=`echo "${RKHLINE}" | cut -d: -f$RKH_CC` | |
| fi | |
| RKHDTM=`echo "${RKHTMPVAR}" | cut -d' ' -f9` | |
| # | |
| # Now get the inode value. | |
| # | |
| RKHTMPVAR="" | |
| test -n "${INODECMD}" && RKHTMPVAR=`eval ${INODECMD} "\"${FNAME}\"" 2>/dev/null | tr -d ' '` | |
| # | |
| # Finally, get the file name. To do this we adjust RKH_CC back one field. | |
| # | |
| RKH_CC2=`expr $RKH_CC - 1` | |
| RKHTMPVAR2=`echo "${RKHLINE}" | cut -d: -f1-$RKH_CC2` | |
| # | |
| # Now put it all together. | |
| # | |
| RKHLINE="${RKHTMPVAR2}:${RKHHASH}:${RKHTMPVAR}:${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}" | |
| fi | |
| fi | |
| # | |
| # Do the file hash value check. | |
| # | |
| if [ $SKIP_HASH -eq 0 ]; then | |
| # | |
| # First we get all the package manager results. | |
| # | |
| case "${PKGMGR}" in | |
| RPM) | |
| ;; | |
| DPKG) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| PKGNAME="" | |
| else | |
| PKGNAME=`${DPKG_CMD} --search "${FNAME}" 2>/dev/null | cut -d: -f1` | |
| fi | |
| if [ -n "${PKGNAME}" -a -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then | |
| FNGREP=`echo "${FNAMEGREP}" | sed -e 's:^/::'` | |
| SYSHASH=`grep -E "( |\./)${FNGREP}\$" "/var/lib/dpkg/info/${PKGNAME}.md5sums" | cut -d' ' -f1` | |
| if [ -n "${SYSHASH}" ]; then | |
| FILE_IS_PKGD=1 | |
| RKHTMPVAR=`${PKGMGR_MD5_HASH} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| ;; | |
| BSD) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| PKGNAME="" | |
| if [ $NOVRFYFILE -eq 0 ]; then | |
| RKHTMPVAR=`${PKG_CMD} -F -e "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| if [ $ERRCODE -ne 0 ]; then | |
| # | |
| # It may be that we need to use the '-W' option instead. | |
| # | |
| RKHTMPVAR=`${PKG_CMD} -q -W "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| fi | |
| if [ $ERRCODE -eq 0 -a -n "${RKHTMPVAR}" ]; then | |
| PKGNAME=`echo "${RKHTMPVAR}" | tail ${TAIL_OPT}1` | |
| fi | |
| fi | |
| if [ -n "${PKGNAME}" ]; then | |
| # | |
| # Next strip off the '/usr/pkg/' or '/usr/local/' from the | |
| # pathname, and then get the hash value. | |
| # | |
| FNGREP=`echo "${FNAMEGREP}" | sed -e 's:^/usr/pkg/::; s:^/usr/local/::'` | |
| SYSHASH=`${PKG_CMD} -v -L "${PKGNAME}" 2>/dev/null | grep -A 1 "File: ${FNGREP}\$" 2>/dev/null | tail ${TAIL_OPT}1 | cut -d: -f3` | |
| if [ -n "${SYSHASH}" ]; then | |
| FILE_IS_PKGD=1 | |
| RKHTMPVAR=`${PKGMGR_MD5_HASH} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| if [ -n "`${PKGMGR_MD5_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| ;; | |
| BSDNG) | |
| # | |
| # First see if the file is exempt or part of a known package. | |
| # | |
| if [ $NOVRFYFILE -eq 1 ]; then | |
| PKGNAME="" | |
| else | |
| RKHTMPVAR=`${PKG_CMD} which -q "${FNAME}" 2>/dev/null` | |
| ERRCODE=$? | |
| test $ERRCODE -eq 0 && PKGNAME="${RKHTMPVAR}" || PKGNAME="" | |
| fi | |
| if [ -n "${PKGNAME}" ]; then | |
| SYSHASH=`${PKG_CMD} query '%Fp: %Fs' ${PKGNAME} 2>/dev/null | grep "^${FNAME}: " 2>/dev/null | sed -r -e 's/^.*: (1\\$)?([A-Fa-f0-9]+)$/\2/'` | |
| if [ -n "${SYSHASH}" ]; then | |
| FILE_IS_PKGD=1 | |
| RKHTMPVAR=`${PKGMGR_SHA_HASH} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| if [ -n "`${PKGMGR_SHA_HASH} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| ;; | |
| SOLARIS) | |
| # | |
| # We only use the Solaris package manager | |
| # hash value if we have been told to do so. | |
| # | |
| if [ $NOVRFYFILE -eq 0 -a $USE_SUNSUM -eq 1 ]; then | |
| SYSHASH="${RKHHASH}" | |
| RKHTMPVAR=`${SUM_CMD} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ "${RKHTMPVAR}" != "${SYSHASH}" ]; then | |
| PKGMGR_VERIFY_RESULT="5" | |
| fi | |
| fi | |
| ;; | |
| esac | |
| # | |
| # Now see if we need to work out the hash value or not. | |
| # | |
| RKHHASH=`echo "${RKHLINE}" | cut -d: -f$RKH_CC` | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| if [ "${RKHHASH}" = "ignore-prelink-dep-err" ]; then | |
| if [ $DEPENDENCY_ERR -eq 1 ]; then | |
| DEPENDENCY_ERR=0 | |
| PKGMGR_VERIFY_RESULT="" | |
| display --to LOG --type INFO FILE_PROP_IGNORE_PRELINK_DEP_ERR "`name2text \"${FNAME}\"`" | |
| else | |
| PKGMGR_VERIFY_RESULT="5" | |
| fi | |
| fi | |
| if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E '5|(^..\?)'`" ]; then | |
| HASH_TEST_PASSED=1 | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:hashchanged" | |
| fi | |
| else | |
| # | |
| # The file is not part of a package. So we need | |
| # to compare the on-disk hash value against the | |
| # value in the rkhunter.dat file. | |
| # | |
| # First see if we have a stored hash value. | |
| # | |
| RKHTMPVAR=0 | |
| if [ -z "${RKHHASH}" ]; then | |
| if [ "${HASH_CMD}" = "NONE" ]; then | |
| : | |
| else | |
| # | |
| # Broken links may not give a hash value, so we must check to see if the link is whitelisted. | |
| # | |
| if [ -h "${FNAME}" -a $HAVE_READLINK -eq 1 ]; then | |
| # Check the link target to see if it is whitelisted. | |
| if [ -z "${SYSLNK}" ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| FNGREP=`echo "${SYSLNK}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNGREP}$\"`" ]; then | |
| RKHTMPVAR=1 | |
| if [ ! -e "${FNAME}" -a $VERBOSE_LOGGING -eq 1 ]; then | |
| # Only log this if it is a broken link. | |
| display --to LOG --type INFO FILE_PROP_BROKEN_LINK_WL_TGT "`name2text \"${FNAME}\"`" "`name2text \"${SYSLNK}\"`" | |
| fi | |
| fi | |
| fi | |
| test $RKHTMPVAR -eq 0 && TEST_RESULT="${TEST_RESULT} norkhhash" | |
| fi | |
| fi | |
| if [ $RKHTMPVAR -eq 0 -a -z "${TEST_RESULT}" ]; then | |
| if [ "${HASH_CMD}" = "NONE" ]; then | |
| SYSHASH="" | |
| else | |
| SYSHASH=`${HASH_CMD} "${FNAME}" 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX` | |
| if [ -z "${SYSHASH}" ]; then | |
| if [ -n "`${HASH_CMD} "${FNAME}" 2>&1 | grep -E 'prelink.* (dependenc|adjusting unfinished)'`" ]; then | |
| if [ "${RKHHASH}" = "ignore-prelink-dep-err" ]; then | |
| SYSHASH="${RKHHASH}" | |
| display --to LOG --type INFO FILE_PROP_IGNORE_PRELINK_DEP_ERR "`name2text \"${FNAME}\"`" | |
| else | |
| DEPENDENCY_ERR=1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ "${RKHHASH}" != "${SYSHASH}" ]; then | |
| # | |
| # We must test for cases where a symbolic link becomes broken. In those | |
| # cases the link would have had a hash value, but will now have none. | |
| # If it was whitelisted, then we should not give a warning. | |
| # | |
| if [ -h "${FNAME}" -a ! -e "${FNAME}" ]; then | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| # Check the link target to see if it is whitelisted. | |
| if [ -z "${SYSLNK}" ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| FNGREP=`echo "${SYSLNK}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_BROKEN_LINK_WL_TGT "`name2text \"${FNAME}\"`" "`name2text \"${SYSLNK}\"`" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} hashchanged" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} hashchanged" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} hashchanged" | |
| fi | |
| fi | |
| fi | |
| fi | |
| # | |
| # Because the BSD and DPKG package managers only provide the MD5 | |
| # checksum, and the Solaris package manager does not provide verified | |
| # data, we can assume that any file which is part of a package after | |
| # this test must be an RPM file. | |
| # | |
| test "${PKGMGR}" != "RPM" && FILE_IS_PKGD=0 | |
| fi | |
| # | |
| # Do the file attributes checks. | |
| # | |
| # This checks the files permissions, and the uid/gid. | |
| # The file permissions are also checked to see if 'w' | |
| # has been allowed for all users. If prelinking is not | |
| # in use then the inode, file size, and modification | |
| # date-time are checked as well. | |
| # | |
| if [ $SKIP_ATTR -eq 0 ]; then | |
| # | |
| # First check to see if the file is whitelisted here, | |
| # just the once. It is better than checking after | |
| # each individual attribute test. | |
| # | |
| WL_FILE="" | |
| if [ -n "`echo \"${ATTRWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| WL_FILE="whitelisted" | |
| WHITELIST_RESULT="${WHITELIST_RESULT} attr" | |
| fi | |
| if [ -z "${FDATA}" ]; then | |
| FDATA=`eval ${SCMD} "\"${FNAME}\"" 2>/dev/null | tr ' ' ':'` | |
| # Ensure the file permissions consist of only 4 digits. | |
| if [ -n "`echo ${FDATA} | grep '^[^:]*:0[0-9][0-9][0-9][0-9]:'`" ]; then | |
| FDATA=`echo $FDATA | sed -e 's/^\([^:]*:\)0\(.*\)$/\1\2/'` | |
| fi | |
| fi | |
| if [ -z "${WL_FILE}" -a -n "${FDATA}" ]; then | |
| # | |
| # Check the file permissions. | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'M|(^.\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:permchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 2` | |
| RKHPERM=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSPERM=`echo ${FDATA} | cut -d: -f2` | |
| if [ -n "${RKHPERM}" ]; then | |
| test "${RKHPERM}" != "${SYSPERM}" && TEST_RESULT="${TEST_RESULT} permchanged" | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhperm" | |
| fi | |
| fi | |
| # | |
| # Check the file user-id. | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'U|(^.....\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:uidchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 3` | |
| RKHUID=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSUID=`echo ${FDATA} | cut -d: -f3` | |
| if [ -n "${RKHUID}" ]; then | |
| test "${RKHUID}" != "${SYSUID}" && TEST_RESULT="${TEST_RESULT} uidchanged" | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhuid" | |
| fi | |
| fi | |
| # | |
| # Check the file group-id. | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'G|(^......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:gidchanged" | |
| else | |
| RKH_CC2=`expr $RKH_CC + 4` | |
| RKHGID=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSGID=`echo ${FDATA} | cut -d: -f4` | |
| if [ -n "${RKHGID}" ]; then | |
| test "${RKHGID}" != "${SYSGID}" && TEST_RESULT="${TEST_RESULT} gidchanged" | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhgid" | |
| fi | |
| fi | |
| # | |
| # Check the file inode number. | |
| # | |
| if [ $PRELINKED -eq 0 ]; then | |
| RKH_CC2=`expr $RKH_CC + 1` | |
| RKHINODE=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSINODE=`echo ${FDATA} | cut -d: -f1` | |
| if [ $SKIP_INODE_CHECK -eq 0 ]; then | |
| if [ -n "${RKHINODE}" ]; then | |
| test "${RKHINODE}" != "${SYSINODE}" && TEST_RESULT="${TEST_RESULT} inodechanged" | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhinode" | |
| fi | |
| fi | |
| fi | |
| # | |
| # Check the file size. | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E 'S|(^\?)'`" ]; then | |
| SIZE_TEST_PASSED=1 | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:sizechanged" | |
| fi | |
| elif [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then | |
| RKH_CC2=`expr $RKH_CC + 5` | |
| RKHSIZE=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSSIZE=`echo ${FDATA} | cut -d: -f5` | |
| if [ -n "${RKHSIZE}" ]; then | |
| if [ "${RKHSIZE}" = "${SYSSIZE}" ]; then | |
| SIZE_TEST_PASSED=1 | |
| else | |
| TEST_RESULT="${TEST_RESULT} sizechanged" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhsize" | |
| fi | |
| fi | |
| # | |
| # Check the file modification date-time. | |
| # | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| echo "${PKGMGR_VERIFY_RESULT}" | grep -E 'T|(^.......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:dtmchanged" | |
| elif [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then | |
| RKH_CC2=`expr $RKH_CC + 6` | |
| RKHDTM=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| SYSDTM=`echo ${FDATA} | cut -d: -f6` | |
| if [ -n "${RKHDTM}" ]; then | |
| test "${RKHDTM}" != "${SYSDTM}" && TEST_RESULT="${TEST_RESULT} dtmchanged" | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhdtm" | |
| fi | |
| fi | |
| # | |
| # If the file is a link, then check that the target has not changed. | |
| # | |
| if [ -h "${FNAME}" ]; then | |
| if [ $FILE_IS_PKGD -eq 1 ]; then | |
| if [ -n "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep -E 'L|(^....\?)'`" ]; then | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| # Check the link target to see if it is whitelisted. | |
| if [ -z "${SYSLNK}" ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| FNGREP=`echo "${SYSLNK}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| test -z "${SYSLNK}" && RKHTMPVAR="Unavailable" || RKHTMPVAR=${SYSLNK} | |
| display --to LOG --type INFO FILE_PROP_LINK_WL "`name2text \"${FNAME}\"`" "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:linkchanged" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} verify:linkchanged" | |
| fi | |
| fi | |
| else | |
| RKH_CC2=`expr $RKH_CC + 8` | |
| SYSLNK_CC=`echo ${RKHLINE} | cut -d: -f$RKH_CC2` | |
| RKH_CC2=`expr $RKH_CC + 9` | |
| SYSLNK_CC=`expr $RKH_CC2 + $SYSLNK_CC` | |
| RKHLNK=`echo ${RKHLINE} | cut -d: -f${RKH_CC2}-${SYSLNK_CC}` | |
| if [ $HAVE_READLINK -eq 1 -a -z "${SYSLNK}" ]; then | |
| SYSLNK=`${READLINK_CMD} ${READLINK_OPT} "${FNAME}"` | |
| fi | |
| if [ -n "${RKHLNK}" ]; then | |
| if [ "${RKHLNK}" != "${SYSLNK}" ]; then | |
| FNGREP=`echo "${SYSLNK}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| test -z "${SYSLNK}" && RKHTMPVAR="Unavailable" || RKHTMPVAR="${SYSLNK}" | |
| display --to LOG --type INFO FILE_PROP_LINK_WL "`name2text \"${FNAME}\"`" "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} linkchanged" | |
| fi | |
| fi | |
| else | |
| TEST_RESULT="${TEST_RESULT} norkhlnk" | |
| fi | |
| fi | |
| fi | |
| elif [ -z "${WL_FILE}" ]; then | |
| TEST_RESULT="${TEST_RESULT} sysattrunavail" | |
| fi | |
| # | |
| # Check the file permissions here to see if the 'other' permission | |
| # contains a 'w'. The check is against the octal value. Symbolic | |
| # links are ignored. | |
| # | |
| if [ ! -h "${FNAME}" -a $FILE_IS_PKGD -eq 0 ]; then | |
| WL_FILE="" | |
| if [ -n "`echo \"${WRITEWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| WL_FILE="whitelisted" | |
| WHITELIST_RESULT="${WHITELIST_RESULT} write" | |
| fi | |
| if [ -z "${WL_FILE}" ]; then | |
| SYSPERM=`echo ${FDATA} | cut -d: -f2` | |
| if [ -n "`echo ${SYSPERM} | grep '[2367]\$'`" ]; then | |
| TEST_RESULT="${TEST_RESULT} write" | |
| elif [ -z "${SYSPERM}" ]; then | |
| TEST_RESULT="${TEST_RESULT} syspermunavail" | |
| fi | |
| fi | |
| fi | |
| fi | |
| # | |
| # If we are adding this file to the rkhunter.dat file, then we | |
| # need to remove any failed test results caused by the file | |
| # currently being missing. We then add the file to the list of | |
| # files to be added, and include the detected system attributes | |
| # of the file. | |
| # | |
| if [ $ADDNEWENTRY -eq 1 ]; then | |
| if [ -n "${TEST_RESULT}" ]; then | |
| for RKHTMPVAR in ${TEST_RESULT}; do | |
| case "${RKHTMPVAR}" in | |
| hashchanged|permchanged|uidchanged|gidchanged|inodechanged|sizechanged|dtmchanged|linkchanged) | |
| TEST_RESULT=`echo "${TEST_RESULT}" | sed -e "s/ ${RKHTMPVAR}//"` | |
| ;; | |
| esac | |
| done | |
| fi | |
| if [ $FMTVERSION -eq 0 ]; then | |
| NEWRKHENTRIES="${NEWRKHENTRIES} | |
| File:${FNAME}:${SYSHASH}:${SYSINODE}:${SYSPERM}:${SYSUID}:${SYSGID}:${SYSSIZE}:${SYSDTM}::${SYSLNK}:" | |
| else | |
| RKH_CC=`echo "${FNAME}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| SYSLNK_CC=`echo "${SYSLNK}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| NEWRKHENTRIES="${NEWRKHENTRIES} | |
| File:${RKH_CC}:${FNAME}:${SYSHASH}:${SYSINODE}:${SYSPERM}:${SYSUID}:${SYSGID}:${SYSSIZE}:${SYSDTM}::${SYSLNK_CC}:${SYSLNK}:" | |
| fi | |
| fi | |
| fi | |
| # | |
| # We can now carry out the tests which do not | |
| # require the rkhunter.dat file. | |
| # | |
| # | |
| # Do the file immutable-bit check. | |
| # | |
| if [ $SKIP_IMMUT -eq 0 ]; then | |
| # | |
| # Test if the file is whitelisted. | |
| # | |
| WL_FILE="" | |
| RKHTMPVAR="" | |
| if [ -n "`echo \"${IMMUTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| WL_FILE="whitelisted" | |
| WHITELIST_RESULT="${WHITELIST_RESULT} immutable" | |
| fi | |
| if [ -z "${WL_FILE}" ]; then | |
| if [ $BSDOS -eq 0 ]; then | |
| if [ ! -h "${FNAME}" ]; then | |
| RKHTMPVAR=`${LSATTR_CMD} "${FNAME}" 2>&1 | cut -d' ' -f1 | grep 'i'` | |
| fi | |
| else | |
| RKHTMPVAR=`ls -lno "${FNAME}" 2>&1 | ${AWK_CMD} '{ print $5 }' | grep -E 'uchg|schg|sappnd|uappnd|sunlnk|sunlink|schange|simmutable|sappend|uappend|uchange|uimmutable'` | |
| fi | |
| # | |
| # Reverse the test result if the immutable bit is always set. | |
| # | |
| if [ $IMMUTABLE_SET -eq 1 ]; then | |
| test -n "${RKHTMPVAR}" && RKHTMPVAR="" || RKHTMPVAR="set" | |
| fi | |
| test -n "${RKHTMPVAR}" && TEST_RESULT="${TEST_RESULT} immutable" | |
| fi | |
| fi | |
| # | |
| # Do the file script replacement check. | |
| # | |
| if [ $SKIP_SCRIPT -eq 0 ]; then | |
| # | |
| # If we are using a package manager, and both the hash test | |
| # and the file size test have passed, then we skip the script | |
| # replacement check. The assumption is that to change a file | |
| # with one value remaining the same is possible, but to change | |
| # it such that both are the same is improbable. It would also | |
| # require the package manager database having being corrupted | |
| # as well. | |
| # | |
| if [ $HASH_TEST_PASSED -eq 0 -o $SIZE_TEST_PASSED -eq 0 ]; then | |
| # | |
| # See if the file is whitelisted. | |
| # | |
| WL_FILE="" | |
| SYSSCRIPT="" | |
| if [ -n "`echo \"${SCRIPTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| WL_FILE="whitelisted" | |
| WHITELIST_RESULT="${WHITELIST_RESULT} script" | |
| fi | |
| if [ -z "${WL_FILE}" ]; then | |
| test -n "${BASENAME_CMD}" && RKHTMPVAR=`${BASENAME_CMD} "${FNAME}"` || RKHTMPVAR=`echo "${FNAME}" | sed -e 's:^.*/::'` | |
| if [ "${RKHTMPVAR}" = "rkhunter" ]; then | |
| SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | grep -E -i -v '(shell|/bin/sh) script( |,|$)'` | |
| else | |
| SYSSCRIPT=`${FILE_CMD} "${FNAME}" 2>&1 | tr -d '\n' | tr '[:cntrl:]' '?' | grep -E -i ' script( |,|$)'` | |
| fi | |
| test -n "${SYSSCRIPT}" && TEST_RESULT="${TEST_RESULT} script" | |
| fi | |
| fi | |
| fi | |
| # | |
| # Now output the results. | |
| # | |
| if [ -z "${TEST_RESULT}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 --log-indent 2 --result OK --color GREEN NAME "`name2text \"${FNAME}\"`" | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 --log-indent 2 --result WARNING --color RED NAME "`name2text \"${FNAME}\"`" | |
| PROP_FAILED_COUNT=`expr ${PROP_FAILED_COUNT} + 1` | |
| RKHTMPVAR2=0 | |
| RKHTMPVAR3=0 | |
| for RKHTMPVAR in ${TEST_RESULT}; do | |
| case "${RKHTMPVAR}" in | |
| hashchanged|permchanged|uidchanged|gidchanged|inodechanged|sizechanged|dtmchanged|linkchanged) | |
| if [ $RKHTMPVAR2 -eq 0 ]; then | |
| RKHTMPVAR2=1 | |
| display --to LOG --type WARNING FILE_PROP_CHANGED | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_CHANGED2 "`name2text \"${FNAME}\"`" | |
| fi | |
| case "${RKHTMPVAR}" in | |
| hashchanged) | |
| if [ -z "${SYSHASH}" ]; then | |
| if [ -h "${FNAME}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSHASH_UNAVAIL_BL | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSHASH_UNAVAIL | |
| fi | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSHASH "${SYSHASH}" | |
| fi | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHHASH "${RKHHASH}" | |
| test $DEPENDENCY_ERR -eq 1 && display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "`name2text \"${FNAME}\"`" | |
| ;; | |
| permchanged) | |
| if [ -z "${SYSPERM}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_PERM_UNAVAIL "${RKHPERM}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_PERM "${SYSPERM}" "${RKHPERM}" | |
| fi | |
| ;; | |
| uidchanged) | |
| if [ -z "${SYSUID}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_UID_UNAVAIL "${RKHUID}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_UID "${SYSUID}" "${RKHUID}" | |
| fi | |
| ;; | |
| gidchanged) | |
| if [ -z "${SYSGID}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_GID_UNAVAIL "${RKHGID}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_GID "${SYSGID}" "${RKHGID}" | |
| fi | |
| ;; | |
| inodechanged) | |
| if [ -z "${SYSINODE}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_INODE_UNAVAIL "${RKHINODE}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_INODE "${SYSINODE}" "${RKHINODE}" | |
| fi | |
| ;; | |
| sizechanged) | |
| if [ -z "${SYSSIZE}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SIZE_UNAVAIL "${RKHSIZE}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SIZE "${SYSSIZE}" "${RKHSIZE}" | |
| fi | |
| ;; | |
| dtmchanged) | |
| if [ -z "${SYSDTM}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSDTM_UNAVAIL | |
| else | |
| get_readable_date ${SYSDTM} | |
| if [ -n "${READABLE_DATE}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSDTM "${SYSDTM} (${READABLE_DATE})" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSDTM "${SYSDTM}" | |
| fi | |
| fi | |
| get_readable_date ${RKHDTM} | |
| if [ -n "${READABLE_DATE}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHDTM "${RKHDTM} (${READABLE_DATE})" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHDTM "${RKHDTM}" | |
| fi | |
| ;; | |
| linkchanged) | |
| test -z "${RKHLNK}" && RKHLNK="Unavailable" | |
| test -z "${SYSLNK}" && SYSLNK="Unavailable" | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSLNK "`name2text \"${FNAME}\"`" "`name2text \"${SYSLNK}\"`" | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHLNK "`name2text \"${FNAME}\"`" "`name2text \"${RKHLNK}\"`" | |
| ;; | |
| esac | |
| ;; | |
| verify:hashchanged|verify:permchanged|verify:uidchanged|verify:gidchanged|verify:sizechanged|verify:dtmchanged|verify:linkchanged) | |
| if [ $RKHTMPVAR3 -eq 0 ]; then | |
| RKHTMPVAR3=1 | |
| display --to LOG --type WARNING FILE_PROP_VRFY | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_CHANGED2 "`name2text \"${FNAME}\"`" | |
| test $DEPENDENCY_ERR -eq 1 && display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "`name2text \"${FNAME}\"`" | |
| fi | |
| case "${RKHTMPVAR}" in | |
| verify:hashchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_HASH | |
| if [ "${RKHHASH}" = "ignore-prelink-dep-err" ]; then | |
| display --to LOG --type INFO --log-indent 9 FILE_PROP_IGNORE_PRELINK_DEP_ERR "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| verify:permchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_PERM | |
| ;; | |
| verify:uidchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_UID | |
| ;; | |
| verify:gidchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_GID | |
| ;; | |
| verify:sizechanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_SIZE | |
| ;; | |
| verify:dtmchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_DTM | |
| ;; | |
| verify:linkchanged) | |
| display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_LNK | |
| ;; | |
| esac | |
| ;; | |
| norkhline) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKH_REC "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhhash) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHHASH "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhperm) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHPERM "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhuid) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHUID "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhgid) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHGID "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhinode) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHINODE "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhsize) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHSIZE "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhdtm) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHDTM "`name2text \"${FNAME}\"`" | |
| ;; | |
| norkhlnk) | |
| display --to LOG --type WARNING FILE_PROP_NO_RKHLNK "`name2text \"${FNAME}\"`" | |
| ;; | |
| sysattrunavail) | |
| display --to LOG --type WARNING FILE_PROP_NO_SYSATTR "`name2text \"${FNAME}\"`" | |
| ;; | |
| write) | |
| display --to LOG --type WARNING FILE_PROP_WRITE "`name2text \"${FNAME}\"`" | |
| ;; | |
| syspermunavail) | |
| display --to LOG --type WARNING FILE_PROP_SYSPERM_UNAVAIL "`name2text \"${FNAME}\"`" | |
| ;; | |
| immutable) | |
| if [ $IMMUTABLE_SET -eq 0 ]; then | |
| display --to LOG --type WARNING FILE_PROP_IMMUT "`name2text \"${FNAME}\"`" | |
| else | |
| display --to LOG --type WARNING FILE_PROP_IMMUT_NOT_SET "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| script) | |
| test -n "${BASENAME_CMD}" && RKHTMPVAR4=`${BASENAME_CMD} "${FNAME}"` || RKHTMPVAR4=`echo "${FNAME}" | sed -e 's:^.*/::'` | |
| if [ "${RKHTMPVAR4}" = "rkhunter" ]; then | |
| display --to LOG --type WARNING FILE_PROP_SCRIPT_RKH "`name2text \"${FNAME}\"`" "${SYSSCRIPT}" | |
| else | |
| display --to LOG --type WARNING FILE_PROP_SCRIPT "`name2text \"${FNAME}\"`" "${SYSSCRIPT}" | |
| fi | |
| ;; | |
| esac | |
| done | |
| fi | |
| if [ -n "${WHITELIST_RESULT}" -a $VERBOSE_LOGGING -eq 1 ]; then | |
| for WL_FILE in ${WHITELIST_RESULT}; do | |
| case "${WL_FILE}" in | |
| hash) | |
| RKHTMPVAR="file hash" | |
| ;; | |
| attr) | |
| RKHTMPVAR="file attributes" | |
| ;; | |
| write) | |
| RKHTMPVAR="file write permission" | |
| ;; | |
| immutable) | |
| RKHTMPVAR="file immutable-bit" | |
| ;; | |
| script) | |
| RKHTMPVAR="script replacement" | |
| ;; | |
| esac | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" "${RKHTMPVAR}" | |
| done | |
| fi | |
| IFS=$IFSNL | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # We must now loop through the rkhunter.dat file and see if any filenames | |
| # are missing from the rkhunter_prop_list.dat file. If so, then this | |
| # indicates a (probably wildcarded) file has been removed from the system. | |
| # | |
| if [ $USE_DAT_FILE -eq 1 ]; then | |
| IFS=$IFSNL | |
| for RKHTMPVAR in `grep '^File:' "${RKHDAT_FILE}"`; do | |
| if [ $FMTVERSION -eq 0 ]; then | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| else | |
| RKH_CC=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| RKH_CC2=`expr 3 + $RKH_CC` | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d: -f3-$RKH_CC2` | |
| fi | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`grep \"^${FNAMEGREP}$\" \"${RKH_FILEPROP_LIST}\"`" ]; then | |
| if [ -n "`echo \"${EXISTWHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| # | |
| # Remove the entry from the rkhunter.dat file. | |
| # | |
| if [ $FMTVERSION -eq 0 ]; then | |
| OLDRKHENTRIES="${OLDRKHENTRIES} | |
| File:${FNAME}:.*" | |
| else | |
| OLDRKHENTRIES="${OLDRKHENTRIES} | |
| File:${RKH_CC}:${FNAME}:.*" | |
| fi | |
| elif [ ! -e "${FNAME}" ]; then | |
| PROP_FAILED_COUNT=`expr ${PROP_FAILED_COUNT} + 1` | |
| PROP_FILE_LIST_COUNT=`expr ${PROP_FILE_LIST_COUNT} + 1` | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 --log-indent 2 --result WARNING --color RED NAME "`name2text \"${FNAME}\"`" | |
| display --to LOG --type WARNING FILE_PROP_FILE_NOT_EXIST "`name2text \"${FNAME}\"`" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Finally, add or remove any specified entries to/from the rkhunter.dat file. | |
| # | |
| test -n "${OLDRKHENTRIES}" -o -n "${NEWRKHENTRIES}" && updt_rkhdat | |
| return | |
| } | |
| suspscan() { | |
| # | |
| # Suspscan content scan using fixed strings. | |
| # | |
| # Suspscan is a CPU hog and only useful to some limit. | |
| # Suspscan should NEVER be enabled by default. | |
| # | |
| if `check_test suspscan`; then | |
| display --to LOG --type INFO --nl STARTING_TEST suspscan | |
| display --to LOG --type PLAIN --log-indent 2 SUSPSCAN_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST suspscan | |
| fi | |
| return | |
| fi | |
| # | |
| # First check that we have the commands we need. | |
| # | |
| if [ -z "${FILE_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 SUSPSCAN_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' file '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'file' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'file' | |
| fi | |
| return | |
| elif [ -z "${STRINGS_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 SUSPSCAN_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' strings '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'strings' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'strings' | |
| fi | |
| return | |
| fi | |
| # | |
| # Now check that the suspscan data file is usable. | |
| # | |
| if [ ! -e "${DB_PATH}/suspscan.dat" -o ! -s "${DB_PATH}/suspscan.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK | |
| display --to LOG --type WARNING --log-indent 9 SUSPSCAN_DAT_MISSING "${DB_PATH}/suspscan.dat" | |
| return | |
| elif [ ! -f "${DB_PATH}/suspscan.dat" -o -h "${DB_PATH}/suspscan.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK | |
| display --to LOG --type WARNING --log-indent 9 SUSPSCAN_DAT_NOTAFILE "${DB_PATH}/suspscan.dat" | |
| return | |
| fi | |
| # | |
| # Next log our configuration settings. | |
| # | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SUSPSCAN_DIRS "${SUSPSCAN_DIRS}" | |
| display --to LOG --type INFO SUSPSCAN_TEMP "${SUSPSCAN_TEMP}" | |
| display --to LOG --type INFO SUSPSCAN_SIZE "${SUSPSCAN_MAXSIZE}" | |
| display --to LOG --type INFO SUSPSCAN_THRESH "${SUSPSCAN_THRESH}" | |
| fi | |
| # | |
| # Finally start the test. | |
| # | |
| FOUND=0 | |
| FOUNDDIRS="" | |
| FILENAME="${SUSPSCAN_TEMP}/suspscan.$$.strings" | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| rm -f ${SUSPSCAN_TEMP}/suspscan.*.strings >/dev/null 2>&1 | |
| # | |
| # Get a temporary file used to log the scan results. | |
| # | |
| get_temp_file "${RKHTMPDIR}/suspscan.tmp" | |
| SUSPSCAN_TMPFILE="${TEMPFILE}" | |
| touch "${SUSPSCAN_TMPFILE}" | |
| # | |
| # We expand the whitelist option here to ensure | |
| # that any wildcard entries are the most recent. | |
| # | |
| if [ -n "${SUSPSCAN_WL_OPT}" ]; then | |
| SUSPSCAN_WHITELIST=`expand_paths SUSPSCAN_WL_OPT` | |
| else | |
| SUSPSCAN_WHITELIST="" | |
| fi | |
| for SUSPSCAN_DIR in ${SUSPSCAN_DIRS}; do | |
| if [ -d "${SUSPSCAN_DIR}" ]; then | |
| FOUND=0 | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "4 SUSPSCAN_DIR_CHECK "${SUSPSCAN_DIR}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| $FIND_CMD "${SUSPSCAN_DIR}" -type f -o -type l 2>/dev/null | while read SUSPSCAN_ITEM; do | |
| # | |
| # Skip the debug file which may well be in one of the default suspscan directories. | |
| # | |
| test $DEBUG_OPT -eq 1 -a "${SUSPSCAN_ITEM}" = "${RKHDEBUGFILE}" && continue | |
| # | |
| # If the file is a link, then find what it points to. | |
| # | |
| if [ -h "${SUSPSCAN_ITEM}" ]; then | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| RKHTMPVAR="${SUSPSCAN_ITEM}" | |
| SUSPSCAN_ITEM=`${READLINK_CMD} ${READLINK_OPT} "${RKHTMPVAR}" 2>/dev/null` | |
| if [ -z "${SUSPSCAN_ITEM}" ]; then | |
| continue | |
| elif [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_LINK_CHANGE "${RKHTMPVAR}" "${SUSPSCAN_ITEM}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| else | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_LINK "${SUSPSCAN_ITEM}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| continue | |
| fi | |
| fi | |
| # | |
| # Ignore any whitelisted files. | |
| # | |
| FNAMEGREP=`echo "${SUSPSCAN_ITEM}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${SUSPSCAN_WHITELIST}\" | grep \"^${SUSPSCAN_ITEM}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SUSPSCAN_WL "${SUSPSCAN_ITEM}" | |
| fi | |
| continue | |
| fi | |
| # | |
| # Next check the size of the file. | |
| # | |
| if [ ! -s "${SUSPSCAN_ITEM}" ]; then | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_EMPTY "${SUSPSCAN_ITEM}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| continue | |
| elif [ -z "`${FIND_CMD} "${SUSPSCAN_ITEM}" -size -${SUSPSCAN_MAXSIZE}c 2>/dev/null`" ]; then | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_SIZE "${SUSPSCAN_ITEM}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| continue | |
| fi | |
| # | |
| # Finally, test the file type. | |
| # | |
| FTYPE=`${FILE_CMD} "${SUSPSCAN_ITEM}" 2>&1 | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| # | |
| # We need to check errors from the file command, but not | |
| # if they are caused by the file disappearing beneath us. | |
| # | |
| test ! -e "${SUSPSCAN_ITEM}" && continue | |
| # | |
| # Adding "text" to the egrep below widens scope at the expense of more false-positives and extending running time. | |
| # | |
| if [ -n "`echo \"${FTYPE}\" | grep -v -i 'compres' | grep -E -i 'execu|reloc|shell|libr|data|obj|text'`" ]; then | |
| FOUND=1 | |
| SUSPSCAN_NUM=1; SUSPSCAN_SCORE=0; SUSPSCAN_HITCOUNT=0 | |
| SUSPSCAN_STRINGS="" | |
| $STRINGS_CMD -n 4 -a "${SUSPSCAN_ITEM}" 2>/dev/null | head ${HEAD_OPT}$SUSPSCAN_LINETHRESH >"${FILENAME}" 2>&1 | |
| for SUSPSCAN_STRING in `grep -v '^Version' "${DB_PATH}/suspscan.dat" 2>/dev/null | tail ${TAIL_OPT}1` ; do | |
| # | |
| # Break off if the score already exceeds the threshold. | |
| # | |
| if [ $SUSPSCAN_SCORE -ge $SUSPSCAN_THRESH ]; then | |
| break | |
| fi | |
| SUSPSCAN_TERM="${SUSPSCAN_STRING}" | |
| # | |
| # Searchterm with class. | |
| # | |
| case "${SUSPSCAN_STRING}" in | |
| [a-z]:*) | |
| SUSPSCAN_CLASS=`echo "${SUSPSCAN_STRING}" | cut -d: -f1` | |
| SUSPSCAN_TERM=`echo "${SUSPSCAN_STRING}" | cut -d: -f2-` | |
| ;; | |
| esac | |
| # | |
| # Searchterm with multiplier. | |
| # | |
| case "${SUSPSCAN_STRING}" in | |
| *+[0-9][0-9]*) | |
| SUSPSCAN_TERM=`echo "${SUSPSCAN_TERM}" | cut -d'+' -f1` | |
| SUSPSCAN_MULTIPLIER=`echo "${SUSPSCAN_STRING}" | cut -d'+' -f2` | |
| ;; | |
| esac | |
| grep -i ${SUSPSCAN_TERM} "${FILENAME}" >/dev/null 2>&1 | |
| ERRCODE=$? | |
| if [ $ERRCODE -eq 0 ]; then | |
| if [ "$SUSPSCAN_CLASS" = "$SUSPSCAN_CLASS_PREV" ]; then | |
| SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + 10` | |
| fi | |
| SUSPSCAN_HITS="$SUSPSCAN_NUM ${SUSPSCAN_HITS}" | |
| if [ -n "$SUSPSCAN_MULTIPLIER" ]; then | |
| SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + ${SUSPSCAN_MULTIPLIER}` | |
| unset SUSPSCAN_MULTIPLIER | |
| else | |
| SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + 1` | |
| fi | |
| SUSPSCAN_HITCOUNT=`expr $SUSPSCAN_HITCOUNT + 1` | |
| SUSPSCAN_STRINGS="${SUSPSCAN_STRINGS} ${SUSPSCAN_TERM}" | |
| SUSPSCAN_CLASS_PREV="$SUSPSCAN_CLASS" | |
| fi | |
| SUSPSCAN_NUM=`expr ${SUSPSCAN_NUM} + 1` | |
| done | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_CHECK_DEBUG "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE" "$SUSPSCAN_HITCOUNT" "${SUSPSCAN_STRINGS}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| if [ $SUSPSCAN_SCORE -ge $SUSPSCAN_THRESH ]; then | |
| echo "6 SUSPSCAN_FILE_CHECK "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE"" >>"${SUSPSCAN_TMPFILE}" | |
| echo "SUSPSCAN_INSPECT "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| unset SUSPSCAN_TERM | |
| # | |
| # Compressed or obfuscated. | |
| # | |
| elif [ -n "`echo \"${FTYPE}\" | grep 'corrupted section header size'`" ]; then | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_TYPE "${SUSPSCAN_ITEM}" "Possible UPX-compressed or Dexter01s obfuscated binary"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| # | |
| # ELF ultimate compression kit (ELFuck). | |
| # | |
| elif [ -n "`echo \"${FTYPE}\" | grep 'invalid class invalid byte order'`" ]; then | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_TYPE "${SUSPSCAN_ITEM}" "Possible ELFuck obfuscated binary"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| elif [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| echo "6 SUSPSCAN_FILE_SKIPPED_TYPE "${SUSPSCAN_ITEM}" "${FTYPE}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| done | |
| else | |
| echo "4 SUSPSCAN_DIR_NOT_EXIST "${SUSPSCAN_DIR}"" >>"${SUSPSCAN_TMPFILE}" | |
| fi | |
| done | |
| rm -f ${SUSPSCAN_TEMP}/suspscan.*.strings >/dev/null 2>&1 | |
| # | |
| # Now display the results. | |
| # | |
| cat "${SUSPSCAN_TMPFILE}" | while read LINE; do | |
| LOGCHAR=`echo "$LINE" | cut -c 1` | |
| case "$LOGCHAR" in | |
| 4|6) LOGTYPE=`echo "$LINE" | cut -d ' ' -f 2` | |
| case "$LOGTYPE" in | |
| SUSPSCAN_FILE_SKIPPED_TYPE) | |
| SUSP_SKIP_ITEM=`echo "$LINE" | cut -d ' ' -f 3` | |
| SUSP_SKIP_MSG=`echo "$LINE" | cut -d ' ' -f 4-` | |
| if [ $SUSPSCAN_DEBUG -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent $LOGCHAR $LOGTYPE "${SUSP_SKIP_ITEM}" "${SUSP_SKIP_MSG}" | |
| fi | |
| ;; | |
| *) | |
| display --to LOG --type PLAIN --log-indent $LINE | |
| ;; | |
| esac | |
| ;; | |
| S) | |
| display --to LOG --type WARNING $LINE | |
| ;; | |
| esac | |
| done | |
| FOUNDDIRS=`grep '^6 SUSPSCAN_FILE_CHECK' "${SUSPSCAN_TMPFILE}" 2>/dev/null | head ${HEAD_OPT}1` | |
| if [ -z "${FOUNDDIRS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 SUSPSCAN_CHECK | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| # The 'type' here should be PLAIN, but the loop prevents RKH from seeing that a warning has occurred. | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK | |
| fi | |
| rm -f "${SUSPSCAN_TMPFILE}" >/dev/null 2>&1 | |
| return | |
| } | |
| do_system_commands_checks() { | |
| # | |
| # This function carries out a sequence of tests on | |
| # system commands. These consist of the 'strings' command | |
| # check, library checks and the file properties checks. | |
| # | |
| if `check_test system_commands`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST system_commands | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW CHECK_SYS_COMMANDS | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST system_commands | |
| fi | |
| return | |
| fi | |
| strings_check | |
| shared_libs_check | |
| file_properties_check | |
| keypresspause | |
| return | |
| } | |
| rootkit_file_dir_checks() { | |
| # | |
| # This function performs the check for known rootkit | |
| # files and directories. | |
| # | |
| if `check_test known_rkts`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST known_rkts | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 ROOTKIT_FILES_DIRS_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST known_rkts | |
| fi | |
| return | |
| fi | |
| # 55808 Trojan - Variant A | |
| SCAN_ROOTKIT="55808 Trojan - Variant A" | |
| SCAN_FILES=${W55808A_FILES} | |
| SCAN_DIRS=${W55808A_DIRS} | |
| SCAN_KSYMS=${W55808A_KSYMS} | |
| scanrootkit | |
| # ADM Worm | |
| SCAN_ROOTKIT="ADM Worm" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}" | |
| if [ -f "/etc/passwd" ]; then | |
| RKHTMPVAR=`grep 'w0rm' /etc/passwd` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR 'w0rm' | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, " | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR 'w0rm' | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_STR_FOUND 'w0rm' '/etc/passwd' | |
| fi | |
| else | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_NOFILE '/etc/passwd' | |
| fi | |
| # AjaKit Rootkit | |
| SCAN_ROOTKIT="AjaKit Rootkit" | |
| SCAN_FILES=${AJAKIT_FILES} | |
| SCAN_DIRS=${AJAKIT_DIRS} | |
| SCAN_KSYMS=${AJAKIT_KSYMS} | |
| scanrootkit | |
| # "Adore" Rootkit | |
| SCAN_ROOTKIT="Adore Rootkit" | |
| SCAN_FILES=${AKIT_FILES} | |
| SCAN_DIRS=${AKIT_DIRS} | |
| SCAN_KSYMS=${AKIT_KSYMS} | |
| scanrootkit | |
| # aPa Kit | |
| SCAN_ROOTKIT="aPa Kit" | |
| SCAN_FILES=${APAKIT_FILES} | |
| SCAN_DIRS=${APAKIT_DIRS} | |
| SCAN_KSYMS=${APAKIT_KSYMS} | |
| scanrootkit | |
| # Apache worm | |
| SCAN_ROOTKIT="Apache Worm" | |
| SCAN_FILES=${APACHEWORM_FILES} | |
| SCAN_DIRS=${APACHEWORM_DIRS} | |
| SCAN_KSYMS=${APACHEWORM_KSYMS} | |
| scanrootkit | |
| # Ambient (ark) Rootkit | |
| SCAN_ROOTKIT="Ambient (ark) Rootkit" | |
| SCAN_FILES=${ARK_FILES} | |
| SCAN_DIRS=${ARK_DIRS} | |
| SCAN_KSYMS=${ARK_KSYMS} | |
| scanrootkit | |
| # Balaur Rootkit | |
| SCAN_ROOTKIT="Balaur Rootkit" | |
| SCAN_FILES=${BALAUR_FILES} | |
| SCAN_DIRS=${BALAUR_DIRS} | |
| SCAN_KSYMS=${BALAUR_KSYMS} | |
| scanrootkit | |
| # BeastKit Rootkit | |
| SCAN_ROOTKIT="BeastKit Rootkit" | |
| SCAN_FILES=${BEASTKIT_FILES} | |
| SCAN_DIRS=${BEASTKIT_DIRS} | |
| SCAN_KSYMS=${BEASTKIT_KSYMS} | |
| scanrootkit | |
| # beX2 Rootkit | |
| SCAN_ROOTKIT="beX2 Rootkit" | |
| SCAN_FILES=${BEX_FILES} | |
| SCAN_DIRS=${BEX_DIRS} | |
| SCAN_KSYMS=${BEX_KSYMS} | |
| scanrootkit | |
| # BOBKit Rootkit | |
| SCAN_ROOTKIT="BOBKit Rootkit" | |
| SCAN_FILES=${BOBKIT_FILES} | |
| SCAN_DIRS=${BOBKIT_DIRS} | |
| SCAN_KSYMS=${BOBKIT_KSYMS} | |
| scanrootkit | |
| # OSX Boonana Trojan | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Boonana Trojan" | |
| SCAN_FILES=${BOONANA_FILES} | |
| SCAN_DIRS=${BOONANA_DIRS} | |
| SCAN_KSYMS=${BOONANA_KSYMS} | |
| scanrootkit | |
| fi | |
| # cb Rootkit | |
| SCAN_ROOTKIT="cb Rootkit" | |
| SCAN_FILES=${CB_FILES} | |
| SCAN_DIRS=${CB_DIRS} | |
| SCAN_KSYMS=${CB_KSYMS} | |
| scanrootkit | |
| # CiNIK Worm (Slapper.B variant) | |
| SCAN_ROOTKIT="CiNIK Worm (Slapper.B variant)" | |
| SCAN_FILES=${CINIK_FILES} | |
| SCAN_DIRS=${CINIK_DIRS} | |
| SCAN_KSYMS=${CINIK_KSYMS} | |
| scanrootkit | |
| # CX Rootkit | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="CX Rootkit" | |
| SCAN_FILES=${CXKIT_FILES} | |
| SCAN_DIRS=${CXKIT_DIRS} | |
| SCAN_KSYMS=${CXKIT_KSYMS} | |
| scanrootkit | |
| fi | |
| # Danny-Boy's Abuse Kit | |
| SCAN_ROOTKIT="Danny-Boy's Abuse Kit" | |
| SCAN_FILES=${DANNYBOYS_FILES} | |
| SCAN_DIRS=${DANNYBOYS_DIRS} | |
| SCAN_KSYMS=${DANNYBOYS_KSYMS} | |
| scanrootkit | |
| # Devil RootKit | |
| SCAN_ROOTKIT="Devil RootKit" | |
| SCAN_FILES=${DEVIL_FILES} | |
| SCAN_DIRS=${DEVIL_DIRS} | |
| SCAN_KSYMS=${DEVIL_KSYMS} | |
| scanrootkit | |
| # Diamorphine LKM | |
| SCAN_ROOTKIT="Diamorphine LKM" | |
| SCAN_FILES=${DIAMORPHINE_FILES} | |
| SCAN_DIRS=${DIAMORPHINE_DIRS} | |
| SCAN_KSYMS=${DIAMORPHINE_KSYMS} | |
| scanrootkit | |
| # Dica-Kit Rootkit | |
| SCAN_ROOTKIT="Dica-Kit Rootkit" | |
| SCAN_FILES=${DICA_FILES} | |
| SCAN_DIRS=${DICA_DIRS} | |
| SCAN_KSYMS=${DICA_KSYMS} | |
| scanrootkit | |
| # Dreams RootKit | |
| SCAN_ROOTKIT="Dreams Rootkit" | |
| SCAN_FILES=${DREAMS_FILES} | |
| SCAN_DIRS=${DREAMS_DIRS} | |
| SCAN_KSYMS=${DREAMS_KSYMS} | |
| scanrootkit | |
| # Duarawkz Rootkit | |
| SCAN_ROOTKIT="Duarawkz Rootkit" | |
| SCAN_FILES=${DUARAWKZ_FILES} | |
| SCAN_DIRS=${DUARAWKZ_DIRS} | |
| SCAN_KSYMS=${DUARAWKZ_KSYMS} | |
| scanrootkit | |
| # Ebury sshd backdoor | |
| SCAN_ROOTKIT="Ebury backdoor" | |
| SCAN_FILES=${EBURY_FILES} | |
| SCAN_DIRS=${EBURY_DIRS} | |
| SCAN_KSYMS=${EBURY_KSYMS} | |
| scanrootkit | |
| # Enye LKM | |
| SCAN_ROOTKIT="Enye LKM" | |
| SCAN_FILES=${ENYELKM_FILES} | |
| SCAN_DIRS=${ENYELKM_DIRS} | |
| SCAN_KSYMS=${ENYELKM_KSYMS} | |
| scanrootkit | |
| # Flea Linux Rootkit | |
| SCAN_ROOTKIT="Flea Linux Rootkit" | |
| SCAN_FILES=${FLEA_FILES} | |
| SCAN_DIRS=${FLEA_DIRS} | |
| SCAN_KSYMS=${FLEA_KSYMS} | |
| scanrootkit | |
| # FreeBSD Rootkit | |
| if [ $BSDOS -eq 1 ]; then | |
| SCAN_ROOTKIT="FreeBSD Rootkit" | |
| SCAN_FILES=${FREEBSD_RK_FILES} | |
| SCAN_DIRS=${FREEBSD_RK_DIRS} | |
| SCAN_KSYMS=${FREEBSD_RK_KSYMS} | |
| scanrootkit | |
| fi | |
| # Fu Rootkit | |
| SCAN_ROOTKIT="Fu Rootkit" | |
| SCAN_FILES=${FU_FILES} | |
| SCAN_DIRS=${FU_DIRS} | |
| SCAN_KSYMS=${FU_KSYMS} | |
| scanrootkit | |
| # Fuck`it Rootkit | |
| SCAN_ROOTKIT="Fuck\`it Rootkit" | |
| SCAN_FILES=${FUCKIT_FILES} | |
| SCAN_DIRS=${FUCKIT_DIRS} | |
| SCAN_KSYMS=${FUCKIT_KSYMS} | |
| scanrootkit | |
| # GasKit Rootkit | |
| SCAN_ROOTKIT="GasKit Rootkit" | |
| SCAN_FILES=${GASKIT_FILES} | |
| SCAN_DIRS=${GASKIT_DIRS} | |
| SCAN_KSYMS=${GASKIT_KSYMS} | |
| scanrootkit | |
| # Heroin LKM | |
| SCAN_ROOTKIT="Heroin LKM" | |
| SCAN_FILES=${HEROIN_FILES} | |
| SCAN_DIRS=${HEROIN_DIRS} | |
| SCAN_KSYMS=${HEROIN_KSYMS} | |
| scanrootkit | |
| # HjC Kit | |
| SCAN_ROOTKIT="HjC Kit" | |
| SCAN_FILES=${HJCKIT_FILES} | |
| SCAN_DIRS=${HJCKIT_DIRS} | |
| SCAN_KSYMS=${HJCKIT_KSYMS} | |
| scanrootkit | |
| # ignoKit Rootkit | |
| SCAN_ROOTKIT="ignoKit Rootkit" | |
| SCAN_FILES=${IGNOKIT_FILES} | |
| SCAN_DIRS=${IGNOKIT_DIRS} | |
| SCAN_KSYMS=${IGNOKIT_KSYMS} | |
| scanrootkit | |
| # iLLogiC Rootkit (SunOS Rootkit variant) | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="iLLogiC Rootkit" | |
| SCAN_FILES=${ILLOGIC_FILES} | |
| SCAN_DIRS=${ILLOGIC_DIRS} | |
| SCAN_KSYMS=${ILLOGIC_KSYMS} | |
| scanrootkit | |
| fi | |
| # OSX Inqtana (Variant A) | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Inqtana Worm (Variant A)" | |
| SCAN_FILES=${INQTANAA_FILES} | |
| SCAN_DIRS=${INQTANAA_DIRS} | |
| SCAN_KSYMS=${INQTANAA_KSYMS} | |
| scanrootkit | |
| fi | |
| # OSX Inqtana (Variant B) | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Inqtana Worm (Variant B)" | |
| SCAN_FILES=${INQTANAB_FILES} | |
| SCAN_DIRS=${INQTANAB_DIRS} | |
| SCAN_KSYMS=${INQTANAB_KSYMS} | |
| scanrootkit | |
| fi | |
| # OSX Inqtana (Variant C) | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Inqtana Worm (Variant C)" | |
| SCAN_FILES=${INQTANAC_FILES} | |
| SCAN_DIRS=${INQTANAC_DIRS} | |
| SCAN_KSYMS=${INQTANAC_KSYMS} | |
| scanrootkit | |
| fi | |
| # IntoXonia-NG Rootkit | |
| SCAN_ROOTKIT="IntoXonia-NG Rootkit" | |
| SCAN_FILES=${INTOXONIA_FILES} | |
| SCAN_DIRS=${INTOXONIA_DIRS} | |
| SCAN_KSYMS=${INTOXONIA_KSYMS} | |
| scanrootkit | |
| # Irix Rootkit | |
| SCAN_ROOTKIT="Irix Rootkit" | |
| SCAN_FILES=${IRIXRK_FILES} | |
| SCAN_DIRS=${IRIXRK_DIRS} | |
| SCAN_KSYMS=${IRIXRK_KSYMS} | |
| scanrootkit | |
| # Jynx Rootkit | |
| SCAN_ROOTKIT="Jynx Rootkit" | |
| SCAN_FILES=${JYNX_FILES} | |
| SCAN_DIRS=${JYNX_DIRS} | |
| SCAN_KSYMS=${JYNX_KSYMS} | |
| scanrootkit | |
| # Jynx2 Rootkit | |
| SCAN_ROOTKIT="Jynx2 Rootkit" | |
| SCAN_FILES=${JYNX2_FILES} | |
| SCAN_DIRS=${JYNX2_DIRS} | |
| SCAN_KSYMS=${JYNX2_KSYMS} | |
| scanrootkit | |
| # KBeast Rootkit | |
| SCAN_ROOTKIT="KBeast Rootkit" | |
| SCAN_FILES=${KBEAST_FILES} | |
| SCAN_DIRS=${KBEAST_DIRS} | |
| SCAN_KSYMS=${KBEAST_KSYMS} | |
| scanrootkit | |
| # OSX Keydnap backdoor | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Keydnap backdoor" | |
| SCAN_FILES=${KEYDNAP_FILES} | |
| SCAN_DIRS=${KEYDNAP_DIRS} | |
| SCAN_KSYMS=${KEYDNAP_KSYMS} | |
| scanrootkit | |
| fi | |
| # Kitko Rootkit | |
| SCAN_ROOTKIT="Kitko Rootkit" | |
| SCAN_FILES=${KITKO_FILES} | |
| SCAN_DIRS=${KITKO_DIRS} | |
| SCAN_KSYMS=${KITKO_KSYMS} | |
| scanrootkit | |
| # Knark Rootkit | |
| SCAN_ROOTKIT="Knark Rootkit" | |
| SCAN_FILES=${KNARK_FILES} | |
| SCAN_DIRS=${KNARK_DIRS} | |
| SCAN_KSYMS=${KNARK_KSYMS} | |
| scanrootkit | |
| # OSX Komplex Trojan | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Komplex Trojan" | |
| SCAN_FILES=${KOMPLEX_FILES} | |
| SCAN_DIRS=${KOMPLEX_DIRS} | |
| SCAN_KSYMS=${KOMPLEX_KSYMS} | |
| scanrootkit | |
| fi | |
| # ld-linuxv.so (LD_PRELOAD shared library rootkit) | |
| SCAN_ROOTKIT="ld-linuxv.so Rootkit" | |
| SCAN_FILES=${LINUXV_FILES} | |
| SCAN_DIRS=${LINUXV_DIRS} | |
| SCAN_KSYMS=${LINUXV_KSYMS} | |
| scanrootkit | |
| # Li0n Worm | |
| SCAN_ROOTKIT="Li0n Worm" | |
| SCAN_FILES=${LION_FILES} | |
| SCAN_DIRS=${LION_DIRS} | |
| SCAN_KSYMS=${LION_KSYMS} | |
| scanrootkit | |
| # Lockit / LJK2 Rootkit | |
| SCAN_ROOTKIT="Lockit / LJK2 Rootkit" | |
| SCAN_FILES=${LOCKIT_FILES} | |
| SCAN_DIRS=${LOCKIT_DIRS} | |
| SCAN_KSYMS=${LOCKIT_KSYMS} | |
| scanrootkit | |
| # Mokes backdoor | |
| SCAN_ROOTKIT="Mokes backdoor" | |
| SCAN_FILES=${MOKES_FILES} | |
| SCAN_DIRS=${MOKES_DIRS} | |
| SCAN_KSYMS=${MOKES_KSYMS} | |
| scanrootkit | |
| # Mood-NT Rootkit | |
| SCAN_ROOTKIT="Mood-NT Rootkit" | |
| SCAN_FILES=${MOODNT_FILES} | |
| SCAN_DIRS=${MOODNT_DIRS} | |
| SCAN_KSYMS=${MOODNT_KSYMS} | |
| scanrootkit | |
| # MRK (MiCrobul?) RootKit | |
| SCAN_ROOTKIT="MRK Rootkit" | |
| SCAN_FILES=${MRK_FILES} | |
| SCAN_DIRS=${MRK_DIRS} | |
| SCAN_KSYMS=${MRK_KSYMS} | |
| scanrootkit | |
| # Ni0 Rootkit | |
| SCAN_ROOTKIT="Ni0 Rootkit" | |
| SCAN_FILES=${NIO_FILES} | |
| SCAN_DIRS=${NIO_DIRS} | |
| SCAN_KSYMS=${NIO_KSYMS} | |
| scanrootkit | |
| # Ohhara Rootkit | |
| SCAN_ROOTKIT="Ohhara Rootkit" | |
| SCAN_FILES=${OHHARA_FILES} | |
| SCAN_DIRS=${OHHARA_DIRS} | |
| SCAN_KSYMS=${OHHARA_KSYMS} | |
| scanrootkit | |
| # Optic Kit Worm | |
| SCAN_ROOTKIT="Optic Kit (Tux) Worm" | |
| SCAN_FILES=${OPTICKIT_FILES} | |
| SCAN_DIRS=${OPTICKIT_DIRS} | |
| SCAN_KSYMS=${OPTICKIT_KSYMS} | |
| scanrootkit | |
| # OSX Rootkit 0.2.1 | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="OS X Rootkit" | |
| SCAN_FILES="${OSXRK_FILES}" | |
| SCAN_DIRS="${OSXRK_DIRS}" | |
| SCAN_KSYMS=${OSXRK_KSYMS} | |
| scanrootkit | |
| fi | |
| # Oz Rootkit | |
| SCAN_ROOTKIT="Oz Rootkit" | |
| SCAN_FILES=${OZ_FILES} | |
| SCAN_DIRS=${OZ_DIRS} | |
| SCAN_KSYMS=${OZ_KSYMS} | |
| scanrootkit | |
| # Phalanx Rootkit | |
| SCAN_ROOTKIT="Phalanx Rootkit" | |
| SCAN_FILES=${PHALANX_FILES} | |
| SCAN_DIRS=${PHALANX_DIRS} | |
| SCAN_KSYMS=${PHALANX_KSYMS} | |
| scanrootkit | |
| # Phalanx2 Rootkit (dirs and files) | |
| SCAN_ROOTKIT="Phalanx2 Rootkit" | |
| SCAN_FILES=${PHALANX2_FILES} | |
| SCAN_DIRS=${PHALANX2_DIRS} | |
| SCAN_KSYMS=${PHALANX2_KSYMS} | |
| scanrootkit | |
| # Phalanx2 Rootkit (extended tests) | |
| if [ $LINUXOS -eq 1 ]; then | |
| SCAN_ROOTKIT="Phalanx2 Rootkit (extended tests)" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| ROOTKIT_PHALANX2_TEST=0 | |
| display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}" | |
| if [ $ROOTKIT_PHALANX2_DIRTESTVAL -eq 1 ]; then | |
| ROOTKIT_PHALANX2_DIRNAMES=`${FIND_CMD} /etc /usr -type d -iname "*.p2"` | |
| else | |
| ROOTKIT_PHALANX2_DIRNAMES="/etc/khubd.p2 /etc/lolzz.p2 /usr/lib/zupzz.p2" | |
| fi | |
| if [ -n "${ROOTKIT_PHALANX2_DIRNAMES}" ]; then | |
| for ROOTKIT_PHALANX2_DIRNAME in ${ROOTKIT_PHALANX2_DIRNAMES}; do | |
| if `cd ${ROOTKIT_PHALANX2_DIRNAME} >/dev/null 2>&1`; then | |
| ROOTKIT_PHALANX2_TEST=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "${ROOTKIT_PHALANX2_DIRNAME}" | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_DIR_FOUND "${ROOTKIT_PHALANX2_DIRNAME}" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "${ROOTKIT_PHALANX2_DIRNAME}" | |
| fi | |
| done | |
| elif [ $ROOTKIT_PHALANX2_DIRTESTVAL -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "*.p2" | |
| fi | |
| if `grep -q '^/dev/root .* ext[23] ' /proc/mounts 2>/dev/null`; then | |
| if [ -n "${STAT_CMD}" ]; then | |
| for DIR_NAME in /etc /usr/share; do | |
| if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then | |
| NLINKS1=`${STAT_CMD} --nlink ${DIR_NAME} 2>/dev/null` | |
| else | |
| NLINKS1=`${STAT_CMD} -c %h ${DIR_NAME} 2>/dev/null` | |
| fi | |
| NLINKS2=`ls -ld ${DIR_NAME} 2>/dev/null | ${AWK_CMD} -F' ' '/^d/ {print $2}' 2>/dev/null | head ${HEAD_OPT}1` | |
| test -z "${NLINKS1}" && NLINKS1=-1 | |
| test -z "${NLINKS2}" && NLINKS2=-2 | |
| if [ $NLINKS1 -ne $NLINKS2 ]; then | |
| display --to LOG --type PLAIN --result WARNING --log-indent 2 ROOTKIT_LINK_COUNT "${DIR_NAME}" | |
| if [ $NLINKS1 -eq -1 ]; then | |
| display --to LOG --type PLAIN --log-indent 4 ROOTKIT_LINK_COUNT_CMDERR "${STAT_CMD}" "${DIR_NAME}" | |
| fi | |
| if [ $NLINKS2 -eq -2 ]; then | |
| display --to LOG --type PLAIN --log-indent 4 ROOTKIT_LINK_COUNT_CMDERR 'ls -ld' "${DIR_NAME}" | |
| fi | |
| display --to LOG --type PLAIN --log-indent 4 ROOTKIT_LINK_COUNT_FAIL "${STAT_CMD}" "$NLINKS1" | |
| display --to LOG --type PLAIN --log-indent 4 ROOTKIT_LINK_COUNT_FAIL 'ls -ld' "$NLINKS2" | |
| if [ $ROOTKIT_PHALANX2_TEST -eq 0 ]; then | |
| ROOTKIT_PHALANX2_TEST=1 | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| fi | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_PHALANX2_LINK_COUNT_FAIL "${DIR_NAME}" | |
| else | |
| display --to LOG --type PLAIN --result OK --log-indent 2 ROOTKIT_LINK_COUNT "${DIR_NAME}" | |
| fi | |
| done | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_LINK_COUNT '/etc and /usr/share' | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' stat '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'stat' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'stat' | |
| fi | |
| fi | |
| fi | |
| # On Linux 2.6 kernels certain processes are children of the kthread process which itself is a child of init. | |
| # argv[0] hiding in plain sight works OK (who expects '^ata/0$' processes to be illegal?) but if the parent process Id is not kthread's | |
| # then suspicion is justified. Like other process listing relying on 'ps' the usual process hiding caveat remains. | |
| if [ -n "${PGREP_CMD}" ]; then | |
| if [ -n "`${PGREP_CMD} 'ata/0'`" ]; then | |
| ROOTKIT_PHALANX2_PROC_KTHREAD_PPID=`${PGREP_CMD} -f '^kthread.?$'` | |
| ROOTKIT_PHALANX2_PROC_ATA_PPID=`${PS_CMD} --no-headers -C 'ata/0' -oppid 2>/dev/null` | |
| if [ -n "${ROOTKIT_PHALANX2_PROC_ATA_PPID}" -a -n "${ROOTKIT_PHALANX2_PROC_KTHREAD_PPID}" ]; then | |
| if [ ${ROOTKIT_PHALANX2_PROC_ATA_PPID} -ne ${ROOTKIT_PHALANX2_PROC_KTHREAD_PPID} ]; then | |
| display --to LOG --type PLAIN --result WARNING --log-indent 2 ROOTKIT_PHALANX2_PROC_FOUND | |
| display --to LOG --type PLAIN --log-indent 4 ROOTKIT_PHALANX2_PROC_PPID "${ROOTKIT_PHALANX2_PROC_KTHREAD_PPID}" "${ROOTKIT_PHALANX2_PROC_ATA_PPID}" | |
| if [ $ROOTKIT_PHALANX2_TEST -eq 0 ]; then | |
| ROOTKIT_PHALANX2_TEST=1 | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| fi | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_PHALANX2_PROC_FOUND | |
| else | |
| display --to LOG --type PLAIN --result OK --log-indent 2 ROOTKIT_PHALANX2_PROC | |
| fi | |
| else # ROOTKIT_PHALANX2_PROC_ATA_PPID ps might not support some cmdline args | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_PHALANX2_PROC | |
| display --to LOG --type INFO ROOTKIT_PHALANX2_PROC_PS_ERR | |
| fi | |
| # else # This kernel does not run any 'ata/0' kthread child processes, no warning necessary. | |
| fi | |
| else # PGREP_CMD not found | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_PHALANX2_PROC | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' pgrep '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'pgrep' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'pgrep' | |
| fi | |
| fi | |
| if [ $ROOTKIT_PHALANX2_TEST -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, " | |
| fi | |
| fi | |
| # Portacelo Rootkit | |
| SCAN_ROOTKIT="Portacelo Rootkit" | |
| SCAN_FILES=${PORTACELO_FILES} | |
| SCAN_DIRS=${PORTACELO_DIRS} | |
| SCAN_KSYMS=${PORTACELO_KSYMS} | |
| scanrootkit | |
| # OSX Proton backdoor | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Proton backdoor" | |
| SCAN_FILES=${PROTON_FILES} | |
| SCAN_DIRS=${PROTON_DIRS} | |
| SCAN_KSYMS=${PROTON_KSYMS} | |
| scanrootkit | |
| fi | |
| # R3dstorm Toolkit | |
| SCAN_ROOTKIT="R3dstorm Toolkit" | |
| SCAN_FILES=${REDSTORM_FILES} | |
| SCAN_DIRS=${REDSTORM_DIRS} | |
| SCAN_KSYMS=${REDSTORM_KSYMS} | |
| scanrootkit | |
| # RH-Sharpe's Rootkit | |
| SCAN_ROOTKIT="RH-Sharpe's Rootkit" | |
| SCAN_FILES=${RHSHARPES_FILES} | |
| SCAN_DIRS=${RHSHARPES_DIRS} | |
| SCAN_KSYMS=${RHSHARPES_KSYMS} | |
| scanrootkit | |
| # RSHA's Rootkit | |
| SCAN_ROOTKIT="RSHA's Rootkit" | |
| SCAN_FILES=${RSHA_FILES} | |
| SCAN_DIRS=${RSHA_DIRS} | |
| SCAN_KSYMS=${RSHA_KSYMS} | |
| scanrootkit | |
| # Scalper Worm | |
| SCAN_ROOTKIT="Scalper Worm" | |
| SCAN_FILES=${SCALPER_FILES} | |
| SCAN_DIRS=${SCALPER_DIRS} | |
| SCAN_KSYMS=${SCALPER_KSYMS} | |
| scanrootkit | |
| # Sebek LKM (Honeypot) | |
| SCAN_ROOTKIT="Sebek LKM" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}" | |
| FOUND=0 | |
| if [ -n "${KSYMS_FILE}" ]; then | |
| grep -E -i 'adore|sebek' "${KSYMS_FILE}" >/dev/null 2>&1 && FOUND=1 | |
| fi | |
| if [ $FOUND -eq 0 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ -n "${KSYMS_FILE}" ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM 'adore or sebek' | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_FILES_DIRS_KSYM 'adore or sebek' | |
| fi | |
| fi | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, " | |
| display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM 'adore or sebek' | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_KSYM_FOUND 'adore or sebek' | |
| fi | |
| # Shutdown Rootkit | |
| SCAN_ROOTKIT="Shutdown Rootkit" | |
| SCAN_FILES=${SHUTDOWN_FILES} | |
| SCAN_DIRS=${SHUTDOWN_DIRS} | |
| SCAN_KSYMS=${SHUTDOWN_KSYMS} | |
| scanrootkit | |
| # SHV4 Rootkit | |
| SCAN_ROOTKIT="SHV4 Rootkit" | |
| SCAN_FILES=${SHV4_FILES} | |
| SCAN_DIRS=${SHV4_DIRS} | |
| SCAN_KSYMS=${SHV4_KSYMS} | |
| scanrootkit | |
| # SHV5 Rootkit | |
| SCAN_ROOTKIT="SHV5 Rootkit" | |
| SCAN_FILES=${SHV5_FILES} | |
| SCAN_DIRS=${SHV5_DIRS} | |
| SCAN_KSYMS=${SHV5_KSYMS} | |
| scanrootkit | |
| # Sin Rootkit | |
| SCAN_ROOTKIT="Sin Rootkit" | |
| SCAN_FILES=${SINROOTKIT_FILES} | |
| SCAN_DIRS=${SINROOTKIT_DIRS} | |
| SCAN_KSYMS=${SINROOTKIT_KSYMS} | |
| scanrootkit | |
| # SInAR Rootkit | |
| if [ $SUNOS -eq 1 ]; then | |
| FOUND=0 | |
| SINARFILES="" | |
| SCAN_ROOTKIT="SInAR Rootkit" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}" | |
| if [ -n "${FIND_CMD}" ]; then | |
| for DIR in ${BINPATHS}; do | |
| FOUNDINDIR="NOT_FOUND" | |
| for FNAME in `${FIND_CMD} "${DIR}" -type f -name "*[sS][iI][nN][aA][rR]*" 2>/dev/null`; do | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "${FNAME}" known_rkts | |
| fi | |
| elif `grep -i 'sinar' "${FNAME}" >/dev/null 2>&1`; then | |
| FOUND=1 | |
| FOUNDINDIR="FOUND" | |
| SINARFILES="${SINARFILES} ${FNAME}" | |
| fi | |
| done | |
| display --to LOG --type PLAIN --result "${FOUNDINDIR}" --log-indent 2 ROOTKIT_FILES_DIRS_SINAR_DIR "${DIR}" | |
| done | |
| # | |
| # Now display the result. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, " | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_SINAR "${SINARFILES}" | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 NAME "${SCAN_ROOTKIT}" | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' find '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'find' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'find' | |
| fi | |
| fi | |
| fi | |
| # Slapper Worm | |
| SCAN_ROOTKIT="Slapper Worm" | |
| SCAN_FILES=${SLAPPER_FILES} | |
| SCAN_DIRS=${SLAPPER_DIRS} | |
| SCAN_KSYMS=${SLAPPER_KSYMS} | |
| scanrootkit | |
| # Sneakin Rootkit | |
| SCAN_ROOTKIT="Sneakin Rootkit" | |
| SCAN_FILES=${SNEAKIN_FILES} | |
| SCAN_DIRS=${SNEAKIN_DIRS} | |
| SCAN_KSYMS=${SNEAKIN_KSYMS} | |
| scanrootkit | |
| # Solaris Wanuk backdoor | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="Solaris Wanuk backdoor" | |
| SCAN_FILES=${WANUKDOOR_FILES} | |
| SCAN_DIRS=${WANUKDOOR_DIRS} | |
| SCAN_KSYMS=${WANUKDOOR_KSYMS} | |
| scanrootkit | |
| fi | |
| # Solaris Wanuk Worm | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="Solaris Wanuk Worm" | |
| SCAN_FILES=${WANUKWORM_FILES} | |
| SCAN_DIRS=${WANUKWORM_DIRS} | |
| SCAN_KSYMS=${WANUKWORM_KSYMS} | |
| scanrootkit | |
| fi | |
| # 'Spanish' Rootkit | |
| SCAN_ROOTKIT="'Spanish' Rootkit" | |
| SCAN_FILES=${SPANISH_FILES} | |
| SCAN_DIRS=${SPANISH_DIRS} | |
| SCAN_KSYMS=${SPANISH_KSYMS} | |
| scanrootkit | |
| # Suckit Rootkit | |
| SCAN_ROOTKIT="Suckit Rootkit" | |
| SCAN_FILES=${SUCKIT_FILES} | |
| SCAN_DIRS=${SUCKIT_DIRS} | |
| SCAN_KSYMS=${SUCKIT_KSYMS} | |
| scanrootkit | |
| # SunOS Rootkit | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="SunOS Rootkit" | |
| SCAN_FILES=${SUNOSROOTKIT_FILES} | |
| SCAN_DIRS=${SUNOSROOTKIT_DIRS} | |
| SCAN_KSYMS=${SUNOSROOTKIT_KSYMS} | |
| scanrootkit | |
| fi | |
| # SunOS / NSDAP Rootkit | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="SunOS / NSDAP Rootkit" | |
| SCAN_FILES=${NSDAP_FILES} | |
| SCAN_DIRS=${NSDAP_DIRS} | |
| SCAN_KSYMS=${NSDAP_KSYMS} | |
| scanrootkit | |
| fi | |
| # Superkit Rootkit | |
| SCAN_ROOTKIT="Superkit Rootkit" | |
| SCAN_FILES=${SUPERKIT_FILES} | |
| SCAN_DIRS=${SUPERKIT_DIRS} | |
| SCAN_KSYMS=${SUPERKIT_KSYMS} | |
| scanrootkit | |
| # TBD (Telnet BackDoor) | |
| SCAN_ROOTKIT="TBD (Telnet BackDoor)" | |
| SCAN_FILES=${TBD_FILES} | |
| SCAN_DIRS=${TBD_DIRS} | |
| SCAN_KSYMS=${TBD_KSYMS} | |
| scanrootkit | |
| # TeLeKiT Rootkit | |
| SCAN_ROOTKIT="TeLeKiT Rootkit" | |
| SCAN_FILES=${TELEKIT_FILES} | |
| SCAN_DIRS=${TELEKIT_DIRS} | |
| SCAN_KSYMS=${TELEKIT_KSYMS} | |
| scanrootkit | |
| # OSX Togroot Rootkit | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="Togroot Rootkit" | |
| SCAN_FILES=${TOGROOT_FILES} | |
| SCAN_DIRS=${TOGROOT_DIRS} | |
| SCAN_KSYMS=${TOGROOT_KSYMS} | |
| scanrootkit | |
| fi | |
| # T0rn Rootkit | |
| SCAN_ROOTKIT="T0rn Rootkit" | |
| SCAN_FILES=${TORN_FILES} | |
| SCAN_DIRS=${TORN_DIRS} | |
| SCAN_KSYMS=${TORN_KSYMS} | |
| scanrootkit | |
| # TrNkit Rootkit | |
| SCAN_ROOTKIT="trNkit Rootkit" | |
| SCAN_FILES=${TRNKIT_FILES} | |
| SCAN_DIRS=${TRNKIT_DIRS} | |
| SCAN_KSYMS=${TRNKIT_KSYMS} | |
| scanrootkit | |
| # Trojanit Kit | |
| SCAN_ROOTKIT="Trojanit Kit" | |
| SCAN_FILES=${TROJANIT_FILES} | |
| SCAN_DIRS=${TROJANIT_DIRS} | |
| SCAN_KSYMS=${TROJANIT_KSYMS} | |
| scanrootkit | |
| # Turtle / Turtle2 Rootkit | |
| if [ $BSDOS -eq 1 ]; then | |
| SCAN_ROOTKIT="Turtle Rootkit" | |
| SCAN_FILES=${TURTLE_FILES} | |
| SCAN_DIRS=${TURTLE_DIRS} | |
| SCAN_KSYMS=${TURTLE_KSYMS} | |
| scanrootkit | |
| fi | |
| # Tuxtendo Rootkit | |
| SCAN_ROOTKIT="Tuxtendo Rootkit" | |
| SCAN_FILES=${TUXTENDO_FILES} | |
| SCAN_DIRS=${TUXTENDO_DIRS} | |
| SCAN_KSYMS=${TUXTENDO_KSYMS} | |
| scanrootkit | |
| # Universal Rootkit by K2 (URK) | |
| SCAN_ROOTKIT="URK Rootkit" | |
| SCAN_FILES=${URK_FILES} | |
| SCAN_DIRS=${URK_DIRS} | |
| SCAN_KSYMS=${URK_KSYMS} | |
| scanrootkit | |
| # Vampire Rootkit | |
| SCAN_ROOTKIT="Vampire Rootkit" | |
| SCAN_FILES=${VAMPIRE_FILES} | |
| SCAN_DIRS=${VAMPIRE_DIRS} | |
| SCAN_KSYMS=${VAMPIRE_KSYMS} | |
| scanrootkit | |
| # VcKit Rootkit | |
| SCAN_ROOTKIT="VcKit Rootkit" | |
| SCAN_FILES=${VCKIT_FILES} | |
| SCAN_DIRS=${VCKIT_DIRS} | |
| SCAN_KSYMS=${VCKIT_KSYMS} | |
| scanrootkit | |
| # Volc Rootkit | |
| SCAN_ROOTKIT="Volc Rootkit" | |
| SCAN_FILES=${VOLC_FILES} | |
| SCAN_DIRS=${VOLC_DIRS} | |
| SCAN_KSYMS=${VOLC_KSYMS} | |
| scanrootkit | |
| # weaponX Rootkit | |
| if [ $MACOSX -eq 1 ]; then | |
| SCAN_ROOTKIT="weaponX Rootkit" | |
| SCAN_FILES=${WEAPONX_FILES} | |
| SCAN_DIRS=${WEAPONX_DIRS} | |
| SCAN_KSYMS=${WEAPONX_KSYMS} | |
| scanrootkit | |
| fi | |
| # Xzibit Rootkit | |
| SCAN_ROOTKIT="Xzibit Rootkit" | |
| SCAN_FILES=${XZIBIT_FILES} | |
| SCAN_DIRS=${XZIBIT_DIRS} | |
| SCAN_KSYMS=${XZIBIT_KSYMS} | |
| scanrootkit | |
| # X-Org SunOS Rootkit | |
| if [ $SUNOS -eq 1 ]; then | |
| SCAN_ROOTKIT="X-Org SunOS Rootkit" | |
| SCAN_FILES=${XORGSUNOS_FILES} | |
| SCAN_DIRS=${XORGSUNOS_DIRS} | |
| SCAN_KSYMS=${XORGSUNOS_KSYMS} | |
| scanrootkit | |
| fi | |
| # zaRwT.KiT Rootkit | |
| SCAN_ROOTKIT="zaRwT.KiT Rootkit" | |
| SCAN_FILES=${ZARWT_FILES} | |
| SCAN_DIRS=${ZARWT_DIRS} | |
| SCAN_KSYMS=${ZARWT_KSYMS} | |
| scanrootkit | |
| # ZK Rootkit | |
| SCAN_ROOTKIT="ZK Rootkit" | |
| SCAN_FILES=${ZK_FILES} | |
| SCAN_DIRS=${ZK_DIRS} | |
| SCAN_KSYMS=${ZK_KSYMS} | |
| scanrootkit | |
| return | |
| } | |
| possible_rootkit_file_dir_checks() { | |
| # | |
| # This function performs the check for possible rootkit | |
| # files and directories. | |
| # | |
| if `check_test possible_rkt_files`; then | |
| display --to LOG --type INFO --nl STARTING_TEST possible_rkt_files | |
| display --to LOG --type PLAIN --log-indent 2 ROOTKIT_POSS_FILES_DIRS_LOG | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST possible_rkt_files | |
| fi | |
| return | |
| fi | |
| FOUND=0 | |
| FOUNDFILES="" | |
| FOUNDDIRS="" | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${FILESCAN}; do | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| RKHTMPVAR=`echo ${RKHTMPVAR} | sed -e 's/^[ ]*//'` | |
| TYPE=`echo ${RKHTMPVAR} | cut -d: -f1` | |
| FILE=`echo ${RKHTMPVAR} | cut -d: -f2` | |
| INFO=`echo ${RKHTMPVAR} | cut -d: -f3` | |
| FNAME=`echo "${FILE}" | tr '%' ' '` | |
| case "${TYPE}" in | |
| dir) | |
| if [ -d "${FNAME}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL_DIR "`name2text \"${FNAME}\"`" 'possible_rkt_files' | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "`name2text \"${FNAME}\"`" | |
| fi | |
| else | |
| FOUND=1 | |
| FOUNDDIRS="${FOUNDDIRS} | |
| ${FNAME}:${INFO}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_DIR "`name2text \"${FNAME}\"`" | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| file) | |
| if [ -f "${FNAME}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'possible_rkt_files' | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| else | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} | |
| ${FNAME}:${INFO}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| *) | |
| echo "Error: Unknown file type in possible rootkit check: FILESCAN contains: ${TYPE}" | |
| ;; | |
| esac | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_POSS_FILES_DIRS | |
| else | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_POSS_FILES_DIRS | |
| IFS=$IFSNL | |
| FOUNDFILES=`echo "${FOUNDFILES}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FOUNDFILES}; do | |
| FILE=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| INFO=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, " | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_FILES_FILE_FOUND "`name2text \"${FILE}\"`" "${INFO}" | |
| done | |
| FOUNDDIRS=`echo "${FOUNDDIRS}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FOUNDDIRS}; do | |
| FILE=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| INFO=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, " | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_FILES_DIR_FOUND "`name2text \"${FILE}\"`" "${INFO}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| return | |
| } | |
| get_rc_paths() { | |
| # | |
| # This function gets a list of the system startup files. | |
| # Directories are searched for files. | |
| # | |
| # This functions will set the variable RC_PATHS. | |
| # | |
| RC_PATHS="" | |
| RKHTMPVAR2="" | |
| # | |
| # For systemd systems we should follow symbolic links, but | |
| # for init systems we do not. Additionally, older UNIX | |
| # systems do not recognise the 'find' command '-L' option. | |
| # (The '-follow' option is now deprecated.) So we need to | |
| # check that '-L' is valid, and only use it if the systemd | |
| # startup directory is being used. | |
| # | |
| FINDFOLLOW=0 | |
| if [ -n "${FIND_CMD}" ]; then | |
| test -z "`${FIND_CMD} -L ${DB_PATH} 2>&1 >/dev/null`" && FINDFOLLOW=1 | |
| fi | |
| if [ -n "${STARTUP_PATHS}" ]; then | |
| RKHTMPVAR="${STARTUP_PATHS}" | |
| else | |
| RKHTMPVAR="${RCLOCATIONS}" | |
| fi | |
| for DIR in ${RKHTMPVAR}; do | |
| test -h "${DIR}" && continue | |
| if [ -f "${DIR}" ]; then | |
| RC_PATHS="${RC_PATHS} | |
| ${DIR}" | |
| RKHTMPVAR2="${RKHTMPVAR2} ${DIR}" | |
| elif [ -d "${DIR}" ]; then | |
| RKHTMPVAR2="${RKHTMPVAR2} ${DIR}" | |
| if [ -n "${FIND_CMD}" ]; then | |
| if [ $FINDFOLLOW -eq 1 -a -n "`echo \"${DIR}\" | grep '^/etc/systemd/'`" ]; then | |
| RKHTMPVAR3=`${FIND_CMD} -L "${DIR}" -type f 2>/dev/null` | |
| else | |
| RKHTMPVAR3=`${FIND_CMD} "${DIR}" -type f -a ! -type l 2>/dev/null` | |
| fi | |
| if [ -n "${RKHTMPVAR3}" ]; then | |
| RC_PATHS="${RC_PATHS} | |
| ${RKHTMPVAR3}" | |
| fi | |
| else | |
| for FNAME in ${DIR}/*; do | |
| test -f "${FNAME}" -a ! -h "${FNAME}" && RC_PATHS="${RC_PATHS} | |
| ${FNAME}" | |
| done | |
| fi | |
| fi | |
| done | |
| if [ $STARTUP_PATHS_LOGGED -eq 0 ]; then | |
| STARTUP_PATHS_LOGGED=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| test -z "${RKHTMPVAR2}" && RKHTMPVAR2="${RKHTMPVAR}" | |
| RKHTMPVAR2=`echo ${RKHTMPVAR2}` | |
| display --to LOG --type INFO CONFIG_STARTUP_PATHS "${RKHTMPVAR2}" | |
| fi | |
| fi | |
| return | |
| } | |
| possible_rootkit_string_checks() { | |
| # | |
| # This function performs the check for possible rootkit | |
| # strings in files. | |
| # | |
| if `check_test possible_rkt_strings`; then | |
| display --to LOG --type INFO --nl STARTING_TEST possible_rkt_strings | |
| display --to LOG --type PLAIN --log-indent 2 ROOTKIT_POSS_STRINGS_LOG | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST possible_rkt_strings | |
| fi | |
| return | |
| fi | |
| # | |
| # First check to see that we can run the test. | |
| # | |
| if [ -z "${STRINGS_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 ROOTKIT_POSS_STRINGS | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' strings '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'strings' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'strings' | |
| fi | |
| return | |
| elif [ "${STARTUP_PATHS}" = "NONE" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color GREEN --screen-indent 4 ROOTKIT_POSS_STRINGS | |
| display --to LOG --type INFO STARTUP_NONE_GIVEN | |
| return | |
| fi | |
| # | |
| # Now get and check that the system startup files are okay. | |
| # | |
| get_rc_paths | |
| if [ -z "${RC_PATHS}" ]; then | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 ROOTKIT_POSS_STRINGS | |
| display --to LOG --type PLAIN --log-indent 9 STARTUP_CHECK_NO_RC_FILES | |
| return | |
| fi | |
| FOUND=0 | |
| FOUNDFILES="" | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${STRINGSCAN}; do | |
| FOUNDFILE=0 | |
| STRINGFOUND=0 | |
| FOUNDSTRING="" | |
| RKHTMPVAR=`echo ${RKHTMPVAR} | sed -e 's/^[ ]*//'` | |
| FILE=`echo ${RKHTMPVAR} | cut -d: -f1` | |
| FILESTRING=`echo ${RKHTMPVAR} | cut -d: -f2` | |
| # If the string begins with '+', then it is already a regular expression. | |
| if [ "`echo ${FILESTRING} | cut -c 1`" = "+" ]; then | |
| STRINGGREP=`echo ${FILESTRING} | cut -c 2-` | |
| FILESTRING="${STRINGGREP}" | |
| else | |
| STRINGGREP=`echo ${FILESTRING} | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| fi | |
| INFO=`echo ${RKHTMPVAR} | cut -d: -f3` | |
| if [ "${FILE}" = "rcfile" ]; then | |
| FOUNDFILE=1 | |
| for FNAME in ${RC_PATHS}; do | |
| FOUNDSTRING=`${STRINGS_CMD} -n 3 -a "${FNAME}" | grep -v '^[ ]*#' | grep "${STRINGGREP}"` | |
| if [ -n "${FOUNDSTRING}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:${STRINGGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL_STR "`name2text \"${FNAME}\"`" "${FILESTRING}" 'possible_rkt_strings' | |
| fi | |
| elif [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" -a -z "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'possible_rkt_strings' | |
| fi | |
| else | |
| FOUND=1 | |
| STRINGFOUND=1 | |
| FOUNDSTRINGS="${FOUNDSTRINGS} | |
| ${FNAME}:${FILESTRING}:${INFO}" | |
| fi | |
| fi | |
| done | |
| else | |
| # | |
| # We cannot use the 'find_cmd' function here because we | |
| # are looking at the command binaries themselves, not | |
| # executing them as commands from the local system. | |
| # | |
| # We need to jiggle with IFS here because we are in | |
| # two loops which are using different field separators. | |
| # | |
| IFS=$RKHIFS | |
| for DIR in ${BINPATHS}; do | |
| FNAME="${DIR}/${FILE}" | |
| if [ -f "${FNAME}" ]; then | |
| FOUNDFILE=1 | |
| FOUNDSTRING=`${STRINGS_CMD} -n 3 -a "${FNAME}" | grep "${STRINGGREP}"` | |
| if [ -n "${FOUNDSTRING}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:${STRINGGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL_STR "`name2text \"${FNAME}\"`" "${FILESTRING}" 'possible_rkt_strings' | |
| fi | |
| elif [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" -a -z "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'possible_rkt_strings' | |
| fi | |
| else | |
| FOUND=1 | |
| STRINGFOUND=1 | |
| FOUNDSTRINGS="${FOUNDSTRINGS} | |
| ${FNAME}:${FILESTRING}:${INFO}" | |
| fi | |
| fi | |
| break | |
| fi | |
| done | |
| fi | |
| if [ $FOUNDFILE -eq 1 ]; then | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| if [ $STRINGFOUND -eq 0 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_STR "${FILESTRING}" | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_STR "${FILESTRING}" | |
| fi | |
| fi | |
| IFS=$IFSNL | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_POSS_STRINGS | |
| else | |
| display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_POSS_STRINGS | |
| IFS=$IFSNL | |
| FOUNDSTRINGS=`echo "${FOUNDSTRINGS}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FOUNDSTRINGS}; do | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| STRING=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| if [ "`echo ${STRING} | cut -c 1`" = "+" ]; then | |
| STRING=`echo ${STRING} | cut -c 2-` | |
| fi | |
| INFO=`echo "${RKHTMPVAR}" | cut -d: -f3` | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, " | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_STRINGS_FOUND "${STRING}" "`name2text \"${FNAME}\"`" "${INFO}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| return | |
| } | |
| additional_rootkit_checks() { | |
| # | |
| # This function performs additional rootkit checks. | |
| # | |
| if `check_test additional_rkts`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST additional_rkts | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 ROOTKIT_ADD_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST additional_rkts | |
| fi | |
| return | |
| fi | |
| test $LINUXOS -eq 1 && suckit_extra_checks | |
| possible_rootkit_file_dir_checks | |
| possible_rootkit_string_checks | |
| return | |
| } | |
| malware_checks() { | |
| # | |
| # This function performs malware checks. | |
| # | |
| if `check_test malware`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST malware | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 ROOTKIT_MALWARE_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST malware | |
| fi | |
| return | |
| fi | |
| # | |
| # First we check for processes using deleted files. | |
| # | |
| if `check_test deleted_files`; then | |
| display --to LOG --type INFO --nl STARTING_TEST deleted_files | |
| if [ -n "${LSOF_CMD}" ]; then | |
| FOUND=0 | |
| WHITEPROC="" | |
| BLACKPROC="" | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| DELE_FILES=`${LSOF_CMD} -wnlP +c 0 ${SOLARISX} 2>/dev/null | grep '(dele' 2>/dev/null | head ${HEAD_OPT}1` | |
| if [ -n "${DELE_FILES}" ]; then | |
| PIDLIST=" " | |
| IFS=$IFSNL | |
| for LINE in `${LSOF_CMD} -wnlP +c 0 ${SOLARISX} 2>/dev/null | grep '(dele'`; do | |
| PROC="" | |
| PID=`echo "${LINE}" | ${AWK_CMD} '{ print $2 }'` | |
| NODE=`echo "${LINE}" | ${AWK_CMD} '{ print $8 }'` | |
| FNAME=`echo "${LINE}" | ${AWK_CMD} '{ print $9 }'` | |
| # | |
| # Skip any PID's we have already seen. | |
| # | |
| test -n "`echo \"${PIDLIST}\" | grep \" $PID \"`" && continue | |
| # | |
| # Try and get the running process name. | |
| # | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| RKHTMPVAR="" | |
| if [ $SOL_PROC -eq 1 ]; then | |
| test -h "/proc/${PID}/path/a.out" && RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "/proc/${PID}/path/a.out"` | |
| elif [ $SUNOS -eq 0 -o -h "/proc/${PID}/exe" ]; then | |
| test -h "/proc/${PID}/exe" && RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "/proc/${PID}/exe"` | |
| fi | |
| test -n "${RKHTMPVAR}" && PROC=`echo "${RKHTMPVAR}" | cut -d' ' -f1` | |
| fi | |
| if [ -z "${PROC}" ]; then | |
| if [ $SUNOS -eq 1 ]; then | |
| PROC=`${LSOF_CMD} -wnlP +c 0 -p $PID 2>/dev/null | grep '[ ]txt[ ][ ]*VREG[ ]' 2>/dev/null | head ${HEAD_OPT}1 | ${AWK_CMD} '{ print $NF }'` | |
| else | |
| PROC=`${LSOF_CMD} -wnlP +c 0 -p $PID 2>/dev/null | grep '[ ]txt[ ][ ]*REG[ ]' | ${AWK_CMD} '{ print $NF }'` | |
| fi | |
| test -z "${PROC}" && PROC=`echo "${LINE}" | ${AWK_CMD} '{ print $1 }'` | |
| fi | |
| # | |
| # If FNAME is not a pathname then look at the NODE. | |
| # | |
| if [ -z "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| if [ -n "`echo \"${NODE}\" | grep '^/'`" ]; then | |
| FNAME="${NODE}" | |
| fi | |
| fi | |
| # | |
| # Strip anything after the pathname. | |
| # | |
| if [ -n "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| FNAME=`echo "${FNAME}" | cut -d' ' -f1` | |
| fi | |
| # | |
| # Now see if the process is whitelisted. | |
| # | |
| PROCWHITELISTED=0 | |
| PROCDELFILES_GIVEN=0 | |
| # | |
| # For this test we do not want to use globbing because it may match with | |
| # files that actually exist. This could then lead to a false-positive for | |
| # what should have been a whitelisted pathname. Instead we disable globbing, | |
| # and then change the glob characters to regular expression ones. We also | |
| # escape typical grep regex characters (e.g. '.'). The resulting regular | |
| # expression is then matched against the deleted file pathname. | |
| # | |
| set -f | |
| for RKHTMPVAR in ${ALLOWPROCDELFILES}; do | |
| RKHTMPVAR2=`echo "${RKHTMPVAR}" | ${AWK_CMD} -F ':/' '{ print $1 }'` | |
| test "${RKHTMPVAR}" = "${RKHTMPVAR2}" && PROCDELFILES_GIVEN=0 || PROCDELFILES_GIVEN=1 | |
| if [ "${PROC}" = "${RKHTMPVAR2}" ]; then | |
| if [ $PROCDELFILES_GIVEN -eq 1 ]; then | |
| RKHTMPVAR3=`echo "${RKHTMPVAR}" | ${AWK_CMD} -F ':/' '{ for (i = 2; i <= NF; i++) { a[i] = $i } } END { for (i in a) { print "/" a[i] } }'` | |
| FNAMEGREP="" | |
| for FN in ${RKHTMPVAR3}; do | |
| FNGREP=`echo "${FN}" | sed -e 's/\([.^+]\)/\\\\\1/g; s/\([^\\]\)\*/\1.*/g; s/\([^\\]\)?/\1./g;'` | |
| FNAMEGREP="${FNAMEGREP}|${FNGREP}" | |
| done | |
| FNAMEGREP=`echo "${FNAMEGREP}" | sed -e 's/^|//;'` | |
| if [ -n "`echo \"${FNAME}\" | grep -E \"^(${FNAMEGREP})$\"`" ]; then | |
| PROCWHITELISTED=1 | |
| fi | |
| else | |
| PROCWHITELISTED=1 | |
| fi | |
| test $PROCWHITELISTED -eq 1 && break | |
| fi | |
| done | |
| set +f | |
| test $HAVE_READLINK -eq 0 && PROC="\"${PROC}\"" | |
| if [ $PROCWHITELISTED -eq 1 ]; then | |
| if [ $PROCDELFILES_GIVEN -eq 1 ]; then | |
| if [ -z "`echo \"${WHITEPROC}\" | grep \"^${PROC} ${FNAME}$\"`" ]; then | |
| WHITEPROC="${WHITEPROC} | |
| ${PROC} ${FNAME}" | |
| fi | |
| elif [ -z "`echo \"${WHITEPROC}\" | grep \"^${PROC}$\"`" ]; then | |
| WHITEPROC="${WHITEPROC} | |
| ${PROC}" | |
| fi | |
| else | |
| FOUND=1 | |
| BLACKPROC="${BLACKPROC} | |
| ${PROC} ${PID} ${FNAME}" | |
| fi | |
| # | |
| # Finally add the PID to the seen PID list. | |
| # | |
| PIDLIST="$PIDLIST $PID " | |
| done | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_DELETED_FILES_FOUND | |
| for LINE in ${BLACKPROC}; do | |
| test -z "${LINE}" && continue | |
| PROC=`echo "$LINE" | cut -d' ' -f1` | |
| PID=`echo "$LINE" | cut -d' ' -f2` | |
| FNAME=`echo "$LINE" | cut -d' ' -f3-` | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_DELETED_FILES_FOUND_DATA "${PROC}" "${PID}" "`name2text \"${FNAME}\"`" | |
| done | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| for RKHTMPVAR in ${WHITEPROC}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep ' /'`" ]; then | |
| PROC=`echo "${RKHTMPVAR}" | cut -d' ' -f1` | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d' ' -f2-` | |
| display --to LOG --type INFO ROOTKIT_MALWARE_DELETED_FILES_WL "${PROC}" "`name2text \"${FNAME}\"`" | |
| else | |
| display --to LOG --type INFO NETWORK_PACKET_CAP_WL "${RKHTMPVAR}" | |
| fi | |
| done | |
| fi | |
| IFS=$RKHIFS | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' lsof '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'lsof' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'lsof' | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST deleted_files | |
| fi | |
| # | |
| # Next we check to see if there any running processes | |
| # using suspicious files. | |
| # | |
| if `check_test running_procs`; then | |
| display --to LOG --type INFO --nl STARTING_TEST running_procs | |
| if [ -n "${LSOF_CMD}" ]; then | |
| # | |
| # First get a temporary file to store the output. | |
| # | |
| get_temp_file "${RKHTMPDIR}/lsofprocs.out" | |
| RKHLSOF_FILE="${TEMPFILE}" | |
| touch "${RKHLSOF_FILE}" | |
| ${LSOF_CMD} -wnlP +c 0 2>&1 | grep -E -v ' (FIFO|V?DIR|IPv[46]) ' | sort | uniq >"${RKHLSOF_FILE}" | |
| # | |
| # Now loop through the known suspicious filenames, | |
| # and see if any are in the lsof output. | |
| # | |
| FOUND=0 | |
| SUSP_FILES="" | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${SUSP_FILES_INFO}; do | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ ]*//'` | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| FOUNDFILES=`grep "/${FNAMEGREP}$" "${RKHLSOF_FILE}"` | |
| if [ -n "${FOUNDFILES}" ]; then | |
| FOUND=0 | |
| INFO=`echo "${RKHTMPVAR}" | cut -d: -f2-` | |
| if [ -n "`echo \"${INFO}\" | grep '^OSX '`" ]; then | |
| if [ $MACOSX -eq 1 ]; then | |
| INFO=`echo "${INFO}" | cut -d' ' -f2-` | |
| else | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT - 1` | |
| continue | |
| fi | |
| fi | |
| # | |
| # It is possible that more than one line of output was found. | |
| # So we must loop through them and record them all. | |
| # | |
| for FNAME in ${FOUNDFILES}; do | |
| # | |
| # See if the filename has been whitelisted. | |
| # | |
| FILENAME=`echo "${FNAME}" | sed -e 's/^.*[ ]\([^ ][^ ]*\)$/\1/'` | |
| FNAMEGREP=`echo "${FILENAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FILENAME}\"`" 'running_procs' | |
| fi | |
| else | |
| FOUND=1 | |
| SUSP_FILES="${SUSP_FILES} | |
| ${RKHTMPVAR}:${FNAME}" | |
| fi | |
| done | |
| if [ $FOUND -eq 1 ]; then | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, " | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| rm -f "${RKHLSOF_FILE}" >/dev/null 2>&1 | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_SUSP_FILES_FOUND | |
| IFS=$IFSNL | |
| SUSP_FILES=`echo "${SUSP_FILES}" | sed -e '/^$/d'` | |
| for FILENAME in ${SUSP_FILES}; do | |
| INFO=`echo ${FILENAME} | cut -d: -f2` | |
| RKHTMPVAR=`echo ${FILENAME} | cut -d: -f3-` | |
| FOUNDINFO=`echo "${RKHTMPVAR}" | ${AWK_CMD} '{ print $1 }'` | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_SUSP_FILES_FOUND_CMD "${FOUNDINFO}" | |
| FOUNDINFO=`echo "${RKHTMPVAR}" | ${AWK_CMD} '{ print $3 }'` | |
| RKHTMPVAR2=`echo "${RKHTMPVAR}" | ${AWK_CMD} '{ print $2 }'` | |
| display --to LOG --type PLAIN --log-indent 11 ROOTKIT_MALWARE_SUSP_FILES_FOUND_UID "${FOUNDINFO}" "${RKHTMPVAR2}" | |
| FOUNDINFO=`echo "${RKHTMPVAR}" | ${AWK_CMD} '{ print $9 }'` | |
| display --to LOG --type PLAIN --log-indent 11 ROOTKIT_MALWARE_SUSP_FILES_FOUND_PATH "${FOUNDINFO}" | |
| display --to LOG --type PLAIN --log-indent 11 ROOTKIT_MALWARE_SUSP_FILES_FOUND_RTKT "${INFO}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' lsof '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'lsof' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'lsof' | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST running_procs | |
| fi | |
| # | |
| # Next we check for any hidden processes. | |
| # | |
| if `check_test hidden_procs`; then | |
| FOUND=0 | |
| UNHIDE_VERS=0 | |
| HIDDEN_PROCS="" | |
| display --to LOG --type INFO --nl STARTING_TEST hidden_procs | |
| # | |
| # First we test for the 'unhide' C program. | |
| # | |
| SEEN=0 | |
| RKHTMPVAR="unhide" | |
| UNHIDE_CMD=`find_cmd unhide` | |
| if [ -z "${UNHIDE_CMD}" ]; then | |
| RKHTMPVAR="unhide-posix" | |
| UNHIDE_CMD=`find_cmd unhide-posix` | |
| fi | |
| if [ $LINUXOS -eq 1 -a -z "${UNHIDE_CMD}" ]; then | |
| RKHTMPVAR="unhide-linux" | |
| UNHIDE_CMD=`find_cmd unhide-linux` | |
| if [ -z "${UNHIDE_CMD}" ]; then | |
| if [ -n "`echo \"${UNAME_R}\" | grep '^2\.6'`" ]; then | |
| RKHTMPVAR="unhide-linux26" | |
| UNHIDE_CMD=`find_cmd unhide-linux26` | |
| fi | |
| fi | |
| fi | |
| if [ -n "${UNHIDE_CMD}" ]; then | |
| FOUND=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FOUND_CMD "${RKHTMPVAR}" "${UNHIDE_CMD}" | |
| fi | |
| # | |
| # Dig out the version number for use later on. | |
| # | |
| UNHIDE_VERS=`${UNHIDE_CMD} -V 2>/dev/null | head ${HEAD_OPT}1` | |
| if [ -n "`echo ${UNHIDE_VERS} | grep '^Unhide [2-9][0-9]*$'`" ]; then | |
| UNHIDE_VERS=`echo ${UNHIDE_VERS} | cut -d' ' -f2` | |
| else | |
| UNHIDE_VERS=0 | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ROOTKIT_MALWARE_HIDDEN_PROCS_UNHIDE_VERS "${UNHIDE_VERS}" | |
| fi | |
| # | |
| # Now run each of the configured tests. | |
| # | |
| UNHIDE_OPTS="" | |
| FOUND_PROCS="" | |
| for RKHTMPVAR in ${UNHIDE_TESTS}; do | |
| if [ -n "`echo \"${RKHTMPVAR} \" | grep '^-'`" ]; then | |
| # Only newer versions have command-line options. | |
| if [ $UNHIDE_VERS -ge 20100919 ]; then | |
| # Ignore obvious invalid options. | |
| test "${RKHTMPVAR}" = "-V" -o "${RKHTMPVAR}" = "-h" && continue | |
| UNHIDE_OPTS="${UNHIDE_OPTS} ${RKHTMPVAR}" | |
| fi | |
| continue | |
| elif [ $UNHIDE_VERS -lt 20100819 ]; then | |
| # Ignore unknown tests for earlier versions. | |
| test "${RKHTMPVAR}" != "sys" -a "${RKHTMPVAR}" != "proc" -a "${RKHTMPVAR}" != "brute" && continue | |
| fi | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| SEEN=1 | |
| FOUND_PROCS=`${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR} 2>&1 | grep -E -v '^(Unhide |yjesus@|http:|Copyright |License |NOTE :|Used options:|\[\*\]|$)'` | |
| if [ -z "${FOUND_PROCS}" ]; then | |
| # Nothing found. | |
| display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS_UNHIDE_CMD "${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR}" | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| # For newer versions we can sort the messages. | |
| if [ $UNHIDE_VERS -ge 20100919 ]; then | |
| FOUND_PROCS=`echo "${FOUND_PROCS}" | sort | uniq` | |
| fi | |
| HIDDEN_PROCS="${HIDDEN_PROCS} | |
| ${FOUND_PROCS}" | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS_UNHIDE_CMD "${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR}" | |
| fi | |
| done | |
| # | |
| # Mark the test as skipped if we have not executed any command because of invalid test names. | |
| # | |
| if [ $SEEN -eq 0 ]; then | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS_UNHIDE_CMD "${UNHIDE_CMD} ${UNHIDE_OPTS} ${RKHTMPVAR}" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NOT_FOUND_CMD 'unhide' | |
| if [ "${RKHTMPVAR}" != "unhide" ]; then | |
| display --to LOG --type INFO NOT_FOUND_CMD "${RKHTMPVAR}" | |
| fi | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| # At this point if SEEN is 0, then a problem occurred with the 'unhide' program. | |
| # We treat these as warnings so that the user is aware that something went | |
| # wrong. | |
| # | |
| HIDDEN_PROCS=`echo "${HIDDEN_PROCS}" | sed -e '/^$/d'` | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS | |
| elif [ -z "${HIDDEN_PROCS}" -a $SEEN -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS | |
| else | |
| # | |
| # At this point we have either found a hidden PID, or an error occurred with the 'unhide' program, | |
| # or both. We need to warn the user in either case. We also need to display all the information. | |
| # | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS | |
| # | |
| # Lets see if there was a problem executing the 'unhide' commands. | |
| # | |
| if [ $SEEN -eq 0 ]; then | |
| display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_HIDDEN_PROCS_UNH_ERR "${UNHIDE_TESTS}" | |
| fi | |
| # | |
| # Now display if any actual hidden PIDs were found. | |
| # | |
| if [ -n "${HIDDEN_PROCS}" ]; then | |
| display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_HIDDEN_PROCS_FOUND | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${HIDDEN_PROCS}; do | |
| display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST hidden_procs | |
| fi | |
| # | |
| # Next we run the check for suspicious file contents. | |
| # | |
| suspscan | |
| # | |
| # Next we check for login backdoors. | |
| # | |
| if `check_test login_backdoors`; then | |
| FOUND=0 | |
| FOUNDFILES="" | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| display --to LOG --type INFO --nl STARTING_TEST login_backdoors | |
| for FNAME in ${LOGIN_BACKDOOR_FILES}; do | |
| if [ -e "${FNAME}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'login_backdoors' | |
| fi | |
| else | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} ${FNAME}" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_MALWARE_LOGIN_BDOOR_CHK "`name2text \"${FNAME}\"`" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_MALWARE_LOGIN_BDOOR_CHK "`name2text \"${FNAME}\"`" | |
| fi | |
| done | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_LOGIN_BDOOR | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_LOGIN_BDOOR | |
| for FNAME in ${FOUNDFILES}; do | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_LOGIN_BDOOR_FOUND "`name2text \"${FNAME}\"`" | |
| done | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST login_backdoors | |
| fi | |
| # | |
| # Next, check for sniffer log files. | |
| # | |
| if `check_test sniffer_logs`; then | |
| FOUND=0 | |
| FOUNDFILES="" | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| display --to LOG --type INFO --nl STARTING_TEST sniffer_logs | |
| for FNAME in ${SNIFFER_FILES}; do | |
| if [ -f "${FNAME}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'sniffer_logs' | |
| fi | |
| else | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} ${FNAME}" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "`name2text \"${FNAME}\"`" | |
| fi | |
| done | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SNIFFER | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SNIFFER | |
| for FNAME in ${FOUNDFILES}; do | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_SNIFFER_FOUND "`name2text \"${FNAME}\"`" | |
| done | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST sniffer_logs | |
| fi | |
| # | |
| # Next we check for any software intrusions. | |
| # | |
| if `check_test tripwire`; then | |
| display --to LOG --type INFO --nl STARTING_TEST tripwire | |
| TRIPWIREFILE="/var/lib/tripwire/`uname -n 2>/dev/null`.twd" | |
| if [ -f "${TRIPWIREFILE}" ]; then | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| if [ -z "`grep ${GREP_OPT} 'Tripwire segment-faulted !' \"${TRIPWIREFILE}\"`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION | |
| display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION_FOUND "${TRIPWIREFILE}" 'Tripwire segment-faulted' | |
| fi | |
| else | |
| if [ -n "`echo \" ${CL_ENABLE_TESTS} \" | grep ' tripwire '`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION | |
| fi | |
| display --to LOG --type INFO ROOTKIT_MALWARE_SFW_INTRUSION_SKIP | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST tripwire | |
| fi | |
| # | |
| # Next check for any suspicious directories. | |
| # | |
| if `check_test susp_dirs`; then | |
| FOUND=0 | |
| FOUNDDIRS="" | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| display --to LOG --type INFO --nl STARTING_TEST susp_dirs | |
| for DIR in ${SUSPICIOUS_DIRS}; do | |
| if [ -d "${DIR}" ]; then | |
| FNAMEGREP=`echo "${DIR}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL_DIR "`name2text \"${DIR}\"`" 'susp_dirs' | |
| fi | |
| else | |
| FOUND=1 | |
| FOUNDDIRS="${FOUNDDIRS} ${DIR}" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "`name2text \"${DIR}\"`" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "`name2text \"${DIR}\"`" | |
| fi | |
| done | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SUSP_DIR | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SUSP_DIR | |
| for DIR in ${FOUNDDIRS}; do | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_SUSP_DIR_FOUND "`name2text \"${DIR}\"`" | |
| done | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST susp_dirs | |
| fi | |
| # | |
| # Next we check the System V Shared Memory (Linux only for now). | |
| # | |
| if `check_test ipc_shared_mem`; then | |
| display --to LOG --type INFO --nl STARTING_TEST ipc_shared_mem | |
| if [ $LINUXOS -eq 1 ]; then | |
| if [ -n "${IPCS_CMD}" ]; then | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| # | |
| # Log the minimum segment size we are going to check. | |
| # If possible, use the human-readable format for the | |
| # number of bytes. | |
| # | |
| IPC_SSIZE_HUMAN=$IPC_SEG_SIZE | |
| if [ $HAVE_NUMFMT -eq 1 ]; then | |
| RKHTMPVAR=`${NUMFMT_CMD} --to iec $IPC_SEG_SIZE 2>/dev/null` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| IPC_SSIZE_HUMAN="${RKHTMPVAR}B" | |
| RKHTMPVAR="$IPC_SEG_SIZE (${IPC_SSIZE_HUMAN})" | |
| else | |
| RKHTMPVAR="$IPC_SEG_SIZE" | |
| fi | |
| else | |
| RKHTMPVAR="$IPC_SEG_SIZE" | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO IPC_SEG_SIZE "$RKHTMPVAR" | |
| fi | |
| # No bad segments found yet. | |
| SEGS_FOUND="" | |
| # No whitelisted entries found yet. | |
| SHM_WL_LIST_PID="" | |
| SHM_WL_LIST_PATH="" | |
| SHM_WL_LIST_USER="" | |
| RKHTMPVAR=`LC_LANG=C ${IPCS_CMD} -u 2>/dev/null | ${AWK_CMD} -F' ' '/segments allocated/ {print $3}'` | |
| test -z "${RKHTMPVAR}" && RKHTMPVAR=0 | |
| if [ $RKHTMPVAR -gt 0 ]; then | |
| # | |
| # We expand the process whitelist option here to ensure | |
| # that any wildcard entries are the most recent. | |
| # | |
| if [ -n "${ALLOWIPCPROC_OPT}" ]; then | |
| ALLOWIPCPROC=`expand_paths ALLOWIPCPROC_OPT` | |
| fi | |
| IFS=$IFSNL | |
| for SHM_LINE in `LC_LANG=C ${IPCS_CMD} -m 2>/dev/null | ${AWK_CMD} -v SHM_SIZE="$IPC_SEG_SIZE" '/^0x/ && ($4 == 600 || $4 == 666) && $5 >= SHM_SIZE { print $0 }'`; do | |
| RKH_SHM_SHMID=`echo "${SHM_LINE}" | ${AWK_CMD} '{ print $2 }'` | |
| RKH_SHM_OWNER=`echo "${SHM_LINE}" | ${AWK_CMD} '{ print $3 }'` | |
| RKH_SHM_SIZE=`echo "${SHM_LINE}" | ${AWK_CMD} '{ print $5 }'` | |
| RKH_SHM_NATTACH=`echo "${SHM_LINE}" | ${AWK_CMD} '{ print $6 }'` | |
| if [ $HAVE_NUMFMT -eq 1 ]; then | |
| RKH_SHM_SIZE_HUMAN=`${NUMFMT_CMD} --to iec $RKH_SHM_SIZE 2>/dev/null` | |
| if [ -n "${RKH_SHM_SIZE_HUMAN}" ]; then | |
| RKH_SHM_SIZE_HUMAN="${RKH_SHM_SIZE_HUMAN}B" | |
| else | |
| RKH_SHM_SIZE_HUMAN=$RKH_SHM_SIZE | |
| fi | |
| else | |
| RKH_SHM_SIZE_HUMAN=$RKH_SHM_SIZE | |
| fi | |
| for SHM_PID_LINE in `LC_LANG=C ${IPCS_CMD} -p 2>/dev/null | grep "^${RKH_SHM_SHMID} "` ; do | |
| RKH_SHM_CPID=`echo "${SHM_PID_LINE}" | ${AWK_CMD} '{ print $3 }'` | |
| RKH_SHM_LPID=`echo "${SHM_PID_LINE}" | ${AWK_CMD} '{ print $4 }'` | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| RKH_SHM_PATH=`${READLINK_CMD} ${READLINK_OPT} /proc/${RKH_SHM_CPID}/exe` | |
| else | |
| # Make an attempt to get the pathname using the 'ls' command. | |
| RKH_SHM_PATH=`ls -l /proc/${RKH_SHM_CPID}/exe | ${AWK_CMD} '{ print $NF }'` | |
| fi | |
| # Strip off the '(deleted)' part from the pathname if present. | |
| RKH_SHM_PATH_STRIPPED=`echo "${RKH_SHM_PATH}" | sed -e 's/ (deleted)$//'` | |
| # | |
| # First check to see if this segment is whitelisted. | |
| # | |
| FOUND=0 | |
| if [ -n "${RKH_SHM_PATH}" ]; then | |
| FNAMEGREP=`echo "${RKH_SHM_PATH_STRIPPED}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${ALLOWIPCPROC}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| FOUND=1 | |
| SHM_WL_LIST_PATH="${SHM_WL_LIST_PATH} `name2text \"${RKH_SHM_PATH_STRIPPED}\"`" | |
| fi | |
| fi | |
| if [ $FOUND -eq 0 -a -n "`echo \"${ALLOWIPCUSER}\" | grep \" ${RKH_SHM_OWNER} \"`" ]; then | |
| FOUND=1 | |
| SHM_WL_LIST_USER="${SHM_WL_LIST_USER} ${RKH_SHM_OWNER}" | |
| fi | |
| if [ $FOUND -eq 0 -a -n "`echo \"${ALLOWIPCPID}\" | grep \" ${RKH_SHM_CPID} \"`" ]; then | |
| FOUND=1 | |
| SHM_WL_LIST_PID="${SHM_WL_LIST_PID} ${RKH_SHM_CPID}" | |
| fi | |
| if [ $FOUND -eq 0 ]; then | |
| # | |
| # We have found a suspicious segment. We just add it to a | |
| # newline-separated list for displaying later on. | |
| # | |
| if [ -n "${RKH_SHM_PATH}" ]; then | |
| RKHTMPVAR2=`name2text "${RKH_SHM_PATH_STRIPPED}"` | |
| if [ "${RKH_SHM_PATH}" = "${RKH_SHM_PATH_STRIPPED}" ]; then | |
| SEGS_FOUND="${SEGS_FOUND} | |
| 1:${RKHTMPVAR2} ${RKH_SHM_CPID} ${RKH_SHM_OWNER} ${RKH_SHM_SIZE_HUMAN} ${IPC_SSIZE_HUMAN}" | |
| else | |
| SEGS_FOUND="${SEGS_FOUND} | |
| 2:${RKHTMPVAR2} ${RKH_SHM_CPID} ${RKH_SHM_OWNER} ${RKH_SHM_SIZE_HUMAN} ${IPC_SSIZE_HUMAN}" | |
| fi | |
| elif [ -n "${RKH_SHM_OWNER}" -a ${RKH_SHM_CPID} -gt 0 ]; then | |
| if [ ${RKH_SHM_NATTACH} -eq 0 ]; then | |
| SEGS_FOUND="${SEGS_FOUND} | |
| 3:${RKH_SHM_OWNER} ${RKH_SHM_CPID} ${RKH_SHM_SHMID} ${RKH_SHM_SIZE_HUMAN} ${IPC_SSIZE_HUMAN}" | |
| else | |
| SEGS_FOUND="${SEGS_FOUND} | |
| 4:${RKH_SHM_OWNER} ${RKH_SHM_SHMID} ${RKH_SHM_NATTACH} ${RKH_SHM_CPID} ${RKH_SHM_LPID} ${RKH_SHM_SIZE_HUMAN} ${IPC_SSIZE_HUMAN}" | |
| fi | |
| fi | |
| fi | |
| done | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${SEGS_FOUND}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_IPCS | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_IPCS | |
| display --to LOG --type WARNING ROOTKIT_MALWARE_IPCS_FOUND | |
| IFS=$IFSNL | |
| for SHM_LINE in ${SEGS_FOUND}; do | |
| test -z "${SHM_LINE}" && continue | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| # We need to do this to ensure the 'set' below works correctly. | |
| IFS=$RKHIFS | |
| SHM_TYPE=`echo "${SHM_LINE}" | cut -d: -f1` | |
| SHM_LINE=`echo "${SHM_LINE}" | cut -d: -f2-` | |
| case "${SHM_TYPE}" in | |
| 1) # A normal segment. | |
| set -- ${SHM_LINE} | |
| # Display $RKH_SHM_PATH, $RKH_SHM_CPID, $RKH_SHM_OWNER, $RKH_SHM_SIZE, $IPC_SEG_SIZE | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_IPCS_DETAILS "$1" "$2" "$3" "$4" "$5" | |
| ;; | |
| 2) # A segment with a deleted pathname. | |
| set -- ${SHM_LINE} | |
| # Display $RKH_SHM_PATH, $RKH_SHM_CPID, $RKH_SHM_OWNER, $RKH_SHM_SIZE, $IPC_SEG_SIZE | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_IPCS_DETAILS "$1 (deleted)" "$2" "$3" "$4" "$5" | |
| ;; | |
| 3) # A detached segment with no pathname. | |
| set -- ${SHM_LINE} | |
| # Display $RKH_SHM_OWNER, $RKH_SHM_CPID, $RKH_SHM_SHMID, $RKH_SHM_SIZE, $IPC_SEG_SIZE | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_IPCS_DETACHED "$1" "$2" "$3" "$4" "$5" | |
| ;; | |
| 4) # An attached segment, but with no pathname. | |
| set -- ${SHM_LINE} | |
| # Display $RKH_SHM_OWNER, $RKH_SHM_SHMID, $RKH_SHM_NATTACH, $RKH_SHM_CPID, $RKH_SHM_LPID, $RKH_SHM_SIZE, $IPC_SEG_SIZE | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_IPCS_ATTACHED "$1" "$2" "$3" "$4" "$5" "$6" "$7" | |
| ;; | |
| esac | |
| IFS=$IFSNL | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Finally display any whitelisted segments that were found. | |
| # | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| FOUND="" | |
| for FNAME in ${SHM_WL_LIST_PATH}; do | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -z "`echo \"${FOUND}\" | grep \" ${FNAMEGREP} \"`" ]; then | |
| FOUND="${FOUND} ${FNAME} " | |
| display --to LOG --type INFO ROOTKIT_MALWARE_IPCS_WL_PATH "${FNAME}" | |
| fi | |
| done | |
| FOUND="" | |
| for FNAME in ${SHM_WL_LIST_USER}; do | |
| if [ -z "`echo \"${FOUND}\" | grep \" ${FNAME} \"`" ]; then | |
| FOUND="${FOUND} ${FNAME} " | |
| display --to LOG --type INFO ROOTKIT_MALWARE_IPCS_WL_USER "${FNAME}" | |
| fi | |
| done | |
| FOUND="" | |
| for FNAME in ${SHM_WL_LIST_PID}; do | |
| if [ -z "`echo \"${FOUND}\" | grep \" ${FNAME} \"`" ]; then | |
| FOUND="${FOUND} ${FNAME} " | |
| display --to LOG --type INFO ROOTKIT_MALWARE_IPCS_WL_PID "${FNAME}" | |
| fi | |
| done | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_IPCS | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ipcs '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ipcs' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ipcs' | |
| fi | |
| fi | |
| else | |
| if [ -n "`echo \" ${CL_ENABLE_TESTS} \" | grep ' ipc_shared_mem '`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_IPCS | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_MALWARE_IPCS | |
| fi | |
| display --to LOG --type INFO LINUX_ONLY | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST ipc_shared_mem | |
| fi | |
| return | |
| } | |
| xinetd_include() { | |
| # | |
| # This function handles the xinetd 'include' directive. | |
| # It is also used to initially process the xinetd.conf | |
| # file, and to process any files within an 'includedir' | |
| # directory. | |
| # | |
| # Any filename containing a dot or ending in a tilde (~) | |
| # is ignored. Also absolute pathnames must be used. | |
| # | |
| FILENAME=$1 | |
| test -z "${FILENAME}" -o ! -f "${FILENAME}" && return | |
| test -z "`echo \"${FILENAME}\" | grep '^/'`" && return | |
| test -n "`echo \"${FILENAME}\" | grep '/[^/]*\.[^/]*$'`" -a "${FILENAME}" != "${XINETD_CONF_PATH}" && return | |
| test -n "`echo \"${FILENAME}\" | grep '~$'`" && return | |
| # | |
| # First see if any defaults have been seen. Only the first instance is used. | |
| # | |
| SEEN=0 | |
| if [ $XINETD_DFLTS_SEEN -eq 0 ]; then | |
| if [ -n "`grep '^defaults' \"${FILENAME}\"`" ]; then | |
| XINETD_DFLTS_SEEN=1 | |
| IFS=$IFSNL | |
| # Get the default enabled services. | |
| for LINE in `grep -E '^[ ]*enabled[ ]*+?=' "${FILENAME}"`; do | |
| SEEN=1 | |
| RKHTMPVAR=`echo "${LINE}" | sed -e 's/^.*=//' | tr -s ' ' ' '` | |
| XINETD_DFLTS_ENABLED="${XINETD_DFLTS_ENABLED} ${RKHTMPVAR}" | |
| done | |
| # We must ensure that the enabled default is | |
| # either the null string or set to something. | |
| if [ -n "${XINETD_DFLTS_ENABLED}" ]; then | |
| XINETD_DFLTS_ENABLED=`echo ${XINETD_DFLTS_ENABLED}` | |
| test -n "${XINETD_DFLTS_ENABLED}" && XINETD_DFLTS_ENABLED=" ${XINETD_DFLTS_ENABLED} " | |
| fi | |
| # Get the default disabled services. | |
| for LINE in `grep -E '^[ ]*disabled[ ]*+?=' "${FILENAME}"`; do | |
| RKHTMPVAR=`echo "${LINE}" | sed -e 's/^.*=//' | tr -s ' ' ' '` | |
| XINETD_DFLTS_DISABLED="${XINETD_DFLTS_DISABLED} ${RKHTMPVAR}" | |
| done | |
| # We must ensure that the disabled default is | |
| # either the null string or set to something. | |
| if [ -n "${XINETD_DFLTS_DISABLED}" ]; then | |
| XINETD_DFLTS_DISABLED=`echo ${XINETD_DFLTS_DISABLED}` | |
| test -n "${XINETD_DFLTS_DISABLED}" && XINETD_DFLTS_DISABLED=" ${XINETD_DFLTS_DISABLED} " | |
| fi | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| # | |
| # Now check to see if an actual service has been configured. | |
| # | |
| if [ -n "`grep '^service' \"${FILENAME}\"`" ]; then | |
| IFS=$IFSNL | |
| # | |
| # We must dig out the service name and its 'id' for each service configured in the file. | |
| # | |
| for DATA in `${AWK_CMD} '/^service/, /^[ ]*\}/ { if ($0 ~ /^[ ]*(#|$)/) next; printf "%s", $0; if ($0 ~ /\}/) print ""; }' "${FILENAME}"`; do | |
| # Unfortunately we must jiggle with IFS again to ensure that subsequent commands work. | |
| IFS=$RKHIFS | |
| # We 'echo' the configured service to flatten out any whitespace. | |
| RKHTMPVAR=`echo ${DATA} | cut -d' ' -f2 | sed -e 's/{$//'` | |
| RKHTMPVAR2=`echo ${DATA} | sed -e 's/^.* id = \([^ ]*\).*$/\1/'` | |
| if [ -z "${RKHTMPVAR2}" ]; then | |
| SVCID=" ${RKHTMPVAR} " | |
| else | |
| SVCID=" (${RKHTMPVAR}|${RKHTMPVAR2}) " | |
| fi | |
| # | |
| # We now check the service name and id against those listed in the defaults. | |
| # | |
| if [ -n "${XINETD_DFLTS_ENABLED}" ]; then | |
| if [ -n "`echo \"${XINETD_DFLTS_ENABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| if [ -z "`echo \"${XINETD_DFLTS_DISABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| SEEN=1 | |
| IFS=$IFSNL | |
| break | |
| fi | |
| fi | |
| elif [ -n "`echo \"${XINETD_DFLTS_DISABLED}\" | grep -E \"${SVCID}\"`" ]; then | |
| : | |
| elif [ -z "`echo $DATA | grep 'disable = yes'`" ]; then | |
| SEEN=1 | |
| IFS=$IFSNL | |
| break | |
| fi | |
| IFS=$IFSNL | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ $SEEN -eq 1 ]; then | |
| # | |
| # See if the file is whitelisted. | |
| # | |
| FOUNDWL=0 | |
| for FNAME in ${XINETDALLOWEDSVCS}; do | |
| if [ "${FNAME}" = "${FILENAME}" ]; then | |
| FOUNDWL=1 | |
| break | |
| fi | |
| done | |
| if [ $FOUNDWL -eq 0 ]; then | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} ${FILENAME}" | |
| display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${FILENAME}" | |
| else | |
| display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${FILENAME}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "${FILENAME}" 'xinetd' | |
| fi | |
| fi | |
| else | |
| display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${FILENAME}" | |
| fi | |
| # | |
| # Next we look for any 'include' directives. | |
| # | |
| for FNAME in `grep '^[ ]*include[ ]' "${FILENAME}" | ${AWK_CMD} '{ print $2 }'`; do | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 6 ROOTKIT_TROJAN_XINETD_INCLUDE "${FNAME}" | |
| fi | |
| xinetd_include "${FNAME}" | |
| done | |
| # | |
| # Finally we look for any 'includedir' directives. | |
| # | |
| for DIR in `grep '^[ ]*includedir[ ]' "${FILENAME}" | ${AWK_CMD} '{ print $2 }'`; do | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 6 ROOTKIT_TROJAN_XINETD_INCLUDEDIR "${DIR}" | |
| fi | |
| xinetd_includedir "${DIR}" | |
| done | |
| return | |
| } | |
| xinetd_includedir() { | |
| # | |
| # This function handles the xinetd 'includedir' directive. | |
| # | |
| # Absolute pathnames must be used. | |
| # | |
| test -z "$1" -o ! -d "$1" && return | |
| test -z "`echo \"$1\" | grep '^/'`" && return | |
| for FNAME in `ls $1`; do | |
| xinetd_include "$1/${FNAME}" | |
| done | |
| return | |
| } | |
| sol10_inetd() { | |
| # | |
| # This function handles the Solaris 10, and later, inetd | |
| # configuration. Because the original inetd.conf file may | |
| # well exist, we look in there as well for any enabled services. | |
| # | |
| # This function sets the FOUNDSTRING variable, which will | |
| # be used later. | |
| # | |
| FOUNDSTRING=`${INETADM_CMD} | grep '^enabled' | cut -d: -f2` | |
| if [ -f "${INETD_CONF_PATH}" ]; then | |
| STR=`grep -v '^#' "${INETD_CONF_PATH}" | ${AWK_CMD} '{ print $1 }'` | |
| # | |
| # Remove any inetd services which we already know | |
| # about from inetadm. | |
| # | |
| for RKHTMPVAR in ${STR}; do | |
| if [ -z "`echo \"${FOUNDSTRING}\" | grep \"/${RKHTMPVAR}/\"`" ]; then | |
| FOUNDSTRING="${FOUNDSTRING} ${RKHTMPVAR}" | |
| fi | |
| done | |
| fi | |
| return | |
| } | |
| trojan_checks() { | |
| # | |
| # This function performs some trojan specific checks. | |
| # | |
| # | |
| # We must first of all remember if the test was named on the command-line. | |
| # | |
| test -n "`echo \" ${CL_ENABLE_TESTS} \" | grep ' trojans '`" && CL_TEST=1 || CL_TEST=0 | |
| if `check_test trojans`; then | |
| display --to LOG --type INFO --nl STARTING_TEST trojans | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST trojans | |
| fi | |
| return | |
| fi | |
| # | |
| # We first need to see if we are running Solaris 10 or later. | |
| # Earlier versions of Solaris used the standard inetd configuration | |
| # file, but later versions use a different mechanism. The 'inetadm' | |
| # command can be used on these later Solaris versions. | |
| # | |
| if [ $SUNOS -eq 1 ]; then | |
| INETADM_CMD=`find_cmd inetadm` | |
| test -n "${INETADM_CMD}" && sol10_inetd | |
| else | |
| INETADM_CMD="" | |
| fi | |
| if [ $CL_TEST -eq 1 ]; then | |
| RKHTMPVAR="SCREEN+LOG --screen-nl" | |
| elif [ -f "${INETD_CONF_PATH}" -o -f "${XINETD_CONF_PATH}" -o -n "${INETADM_CMD}" ]; then | |
| RKHTMPVAR="SCREEN+LOG" | |
| else | |
| RKHTMPVAR="LOG" | |
| fi | |
| display --to ${RKHTMPVAR} --type PLAIN --screen-indent 2 ROOTKIT_TROJAN_START | |
| # | |
| # We first check the inetd.conf file. This includes the | |
| # Solaris 10 inetd services as well. | |
| # | |
| if [ -f "${INETD_CONF_PATH}" -o -n "${INETADM_CMD}" ]; then | |
| if [ -z "${INETADM_CMD}" ]; then | |
| display --to LOG --type INFO CONFIG_XINETD_PATH 'inetd' "${INETD_CONF_PATH}" | |
| FOUNDSTRING=`grep -v '^#' "${INETD_CONF_PATH}" | ${AWK_CMD} '{ print $1 }'` | |
| else | |
| display --to LOG --type INFO CONFIG_SOL10_INETD | |
| fi | |
| # | |
| # We now need to see if any of the services are whitelisted. | |
| # | |
| RKHTMPVAR="" | |
| for STR in ${FOUNDSTRING}; do | |
| FOUND=0 | |
| for SVC in ${INETDALLOWEDSVCS}; do | |
| if [ "${STR}" = "${SVC}" ]; then | |
| FOUND=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "${SVC}" 'inetd' | |
| fi | |
| break | |
| fi | |
| done | |
| if [ $FOUND -eq 0 ]; then | |
| # | |
| # We want to change any RPC services into | |
| # an actual executable name, if we can. The | |
| # executable is the sixth field. If the | |
| # sixth field is empty or this is an internal | |
| # service, then we just use the service name. | |
| # | |
| if [ -n "`echo \"${STR}\" | grep '^[0-9/_-]*$'`" ]; then | |
| EXECNAME=`grep "^${STR}" "${INETD_CONF_PATH}" | ${AWK_CMD} '{ print $6 }'` | |
| test -z "${EXECNAME}" -o "${EXECNAME}" = "internal" && EXECNAME="${STR}" | |
| STR="${EXECNAME}" | |
| # | |
| # Now check if the executable has been whitelisted. | |
| # | |
| for SVC in ${INETDALLOWEDSVCS}; do | |
| if [ "${STR}" = "${SVC}" ]; then | |
| FOUND=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "${SVC}" 'inetd' | |
| fi | |
| break | |
| fi | |
| done | |
| fi | |
| test $FOUND -eq 0 && RKHTMPVAR="${RKHTMPVAR} ${STR}" | |
| fi | |
| done | |
| FOUNDSTRING="${RKHTMPVAR}" | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${FOUNDSTRING}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_TROJAN_INETD | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_TROJAN_INETD | |
| for STR in ${FOUNDSTRING}; do | |
| display --to LOG --type WARNING ROOTKIT_TROJAN_INETD_FOUND "${STR}" | |
| done | |
| fi | |
| else | |
| if [ $CL_TEST -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 --log-indent 2 ROOTKIT_TROJAN_INETD | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_TROJAN_INETD | |
| fi | |
| display --to LOG --type INFO ROOTKIT_TROJAN_INETD_SKIP "${INETD_CONF_PATH}" | |
| fi | |
| # | |
| # Next we check the xinetd.conf file. | |
| # | |
| FOUND=0 | |
| FOUNDFILES="" | |
| if [ -f "${XINETD_CONF_PATH}" ]; then | |
| XINETD_DFLTS_SEEN=0 | |
| XINETD_DFLTS_ENABLED="" | |
| XINETD_DFLTS_DISABLED="" | |
| display --to LOG --type INFO CONFIG_XINETD_PATH 'xinetd' "${XINETD_CONF_PATH}" | |
| xinetd_include "${XINETD_CONF_PATH}" | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_XINETD | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_XINETD | |
| for FNAME in ${FOUNDFILES}; do | |
| display --to LOG --type WARNING ROOTKIT_TROJAN_XINETD_ENABLED_FOUND "${FNAME}" | |
| done | |
| fi | |
| else | |
| if [ $CL_TEST -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_XINETD | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_TROJAN_XINETD | |
| fi | |
| display --to LOG --type INFO ROOTKIT_TROJAN_INETD_SKIP "${XINETD_CONF_PATH}" | |
| fi | |
| # | |
| # Finally we check for an Apache backdoor module. | |
| # | |
| FOUND=0 | |
| FOUNDFILES="" | |
| MOD_DIRS="/etc/apache2/mods-enabled /etc/httpd/modules /usr/apache/libexec /usr/lib/modules /usr/local/apache/modules" | |
| HTTPDDIRS="/usr/local/apache/conf /usr/local/etc/apache /etc/apache /etc/httpd/conf" | |
| for DIR in ${MOD_DIRS} ${HTTPDDIRS}; do | |
| if [ -d "${DIR}" ]; then | |
| FOUND=1 | |
| test -f "${DIR}/mod_rootme.so" && FOUNDFILES="${FOUNDFILES} ${DIR}/mod_rootme.so" | |
| test -f "${DIR}/mod_rootme2.so" && FOUNDFILES="${FOUNDFILES} ${DIR}/mod_rootme2.so" | |
| if [ -f "${DIR}/httpd.conf" ]; then | |
| if [ -n "`grep -E 'mod_rootme2?\.so' \"${DIR}/httpd.conf\"`" ]; then | |
| FOUNDFILES="${FOUNDFILES} ${DIR}/httpd.conf" | |
| fi | |
| fi | |
| fi | |
| done | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| if [ $CL_TEST -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_APACHE | |
| else | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_TROJAN_APACHE | |
| fi | |
| display --to LOG --type INFO ROOTKIT_TROJAN_APACHE_SKIPPED | |
| elif [ -z "${FOUNDFILES}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_APACHE | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_APACHE | |
| for FILE in ${FOUNDFILES}; do | |
| display --to LOG --type WARNING ROOTKIT_TROJAN_APACHE_FOUND "`name2text \"${FILE}\"`" | |
| done | |
| fi | |
| return | |
| } | |
| bsd_specific_checks() { | |
| # | |
| # This function performs tests specific to the BSD O/S. | |
| # | |
| # | |
| # We check that the output of sockstat and netstat for | |
| # local listening sockets is the same. | |
| # | |
| SOCKSTAT_CMD=`find_cmd sockstat` | |
| if [ -n "${SOCKSTAT_CMD}" -a -n "${NETSTAT_CMD}" ]; then | |
| test "${OPERATING_SYSTEM}" = "NetBSD" && RKHTMPVAR="-n" || RKHTMPVAR="" | |
| SOCKSTAT_OUTPUT=`${SOCKSTAT_CMD} ${RKHTMPVAR} | ${AWK_CMD} '$5 ~ /^(tcp|udp)/ { if ($6 == 6) print $7; else print $6 } $4 ~ /^(tcp|udp)/ { if ($5 == 6) print $6; else print $5 }'` | |
| SOCKSTAT_OUTPUT=`echo "${SOCKSTAT_OUTPUT}" | grep '[:.][0-9][0-9]*$' | sed -e 's/^.*[:.]\([0-9]*\)$/\1/' | sort | uniq` | |
| NETSTAT_OUTPUT=`${NETSTAT_CMD} -an | ${AWK_CMD} '$1 ~ /^(tcp|udp)/ { print $4 }' | grep '[:.][0-9][0-9]*$' | sed -e 's/^.*[:.]\([0-9]*\)$/\1/' | sort | uniq` | |
| if [ "${SOCKSTAT_OUTPUT}" = "${NETSTAT_OUTPUT}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET | |
| else | |
| SOCKSTAT_OUTPUT=`echo ${SOCKSTAT_OUTPUT}` | |
| NETSTAT_OUTPUT=`echo ${NETSTAT_OUTPUT}` | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET | |
| display --to LOG --type WARNING ROOTKIT_OS_BSD_SOCKNET_FOUND | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_BSD_SOCKNET_OUTPUT 'Sockstat' "${SOCKSTAT_OUTPUT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_BSD_SOCKNET_OUTPUT 'Netstat' "${NETSTAT_OUTPUT}" | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET | |
| test -z "${SOCKSTAT_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD 'sockstat' | |
| if [ -z "${NETSTAT_CMD}" ]; then | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' netstat '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'netstat' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'netstat' | |
| fi | |
| fi | |
| fi | |
| return | |
| } | |
| freebsd_specific_checks() { | |
| # | |
| # This function performs tests specific to the FreeBSD O/S. | |
| # | |
| # | |
| # First we check for KLD backdoors. | |
| # | |
| KLDSTAT_CMD=`find_cmd kldstat` | |
| if [ -n "${KLDSTAT_CMD}" ]; then | |
| FOUND=0 | |
| FOUNDKEYS="" | |
| for RKHTMPVAR in ${KLDSTATKEYWORDS}; do | |
| RKHTMPVAR=`echo ${RKHTMPVAR}` | |
| KLDKEYWD=`echo ${RKHTMPVAR} | sed -e 's/\./\\\./g'` | |
| if [ -n "`${KLDSTAT_CMD} -v | grep \"${KLDKEYWD}\"`" ]; then | |
| FOUND=1 | |
| FOUNDKEYS="${FOUNDKEYS} ${RKHTMPVAR} " | |
| fi | |
| done | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD | |
| for RKHTMPVAR in ${FOUNDKEYS}; do | |
| display --to LOG --type WARNING ROOTKIT_OS_FREEBSD_KLD_FOUND "${RKHTMPVAR}" | |
| done | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD | |
| display --to LOG --type INFO NOT_FOUND_CMD 'kldstat' | |
| fi | |
| # | |
| # Next we check that the package database is okay. | |
| # | |
| if [ "${OPERATING_SYSTEM}" = "DragonFly" ]; then | |
| PKGDB_CMD=`find_cmd pkg_admin` | |
| if [ -n "${PKGDB_CMD}" ]; then | |
| RKHTMPVAR=`${PKGDB_CMD} check 2>&1 >/dev/null` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| display --to LOG --type WARNING ROOTKIT_OS_DFLY_PKGDB_NOTOK | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| display --to LOG --type INFO NOT_FOUND_CMD 'pkg_admin' | |
| fi | |
| else | |
| PKGDB_CMD=`find_cmd pkgdb` | |
| if [ -n "${PKGDB_CMD}" ]; then | |
| RKHTMPVAR=`${PKGDB_CMD} -Fa -v 2>&1 | grep 'Skipped\.'` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| display --to LOG --type WARNING ROOTKIT_OS_FREEBSD_PKGDB_NOTOK | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB | |
| display --to LOG --type INFO NOT_FOUND_CMD 'pkgdb' | |
| fi | |
| fi | |
| return | |
| } | |
| linux_loaded_modules() { | |
| # | |
| # This test checks the currently loaded kernel modules. It verifies | |
| # that what is seen by the 'lsmod' command is the same as seen in | |
| # the /proc/modules directory. | |
| # | |
| if ! `check_test loaded_modules`; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST loaded_modules | |
| fi | |
| return | |
| fi | |
| if [ ! -f "/proc/modules" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKM | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_MOD_MISSING '/proc/modules' | |
| elif [ -z "${LSMOD_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKM | |
| if [ -z "${LSMOD_CMD}" ]; then | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' lsmod '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'lsmod' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'lsmod' | |
| fi | |
| fi | |
| else | |
| PROC_OUTPUT=`cat /proc/modules | cut -d' ' -f1 | sort` | |
| LSMOD_OUTPUT=`${LSMOD_CMD} | grep -v 'Size *Used *by' | cut -d' ' -f1 | sort` | |
| if [ -n "${PROC_OUTPUT}" -a -n "${LSMOD_OUTPUT}" ]; then | |
| if [ "${PROC_OUTPUT}" = "${LSMOD_OUTPUT}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKM | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKM | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_FOUND | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT '/proc/modules' "${PROC_OUTPUT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT 'lsmod' "${LSMOD_OUTPUT}" | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKM | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_EMPTY | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT '/proc/modules' "${PROC_OUTPUT}" | |
| display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT 'lsmod' "${LSMOD_OUTPUT}" | |
| fi | |
| fi | |
| return | |
| } | |
| linux_avail_modules() { | |
| # | |
| # This test checks the names of the kernel | |
| # modules that are available on this system. | |
| # | |
| if ! `check_test avail_modules`; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST avail_modules | |
| fi | |
| return | |
| fi | |
| # | |
| # First obtain and log where the modules are kept. This can | |
| # be set in the configuration file, but generally rkhunter | |
| # will determine the location based on the kernel version. | |
| # | |
| FOUND=0 | |
| FOUNDFILES="" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ROOTKIT_OS_LINUX_LKMNAMES_PATH "${LKM_PATH}" | |
| fi | |
| # | |
| # Now do the test. | |
| # | |
| if [ ! -d "${LKM_PATH}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKMNAMES_PATH_MISSING "${LKM_PATH}" | |
| elif [ -z "${FIND_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' find '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'find' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'find' | |
| fi | |
| elif [ -z "`ls -1 \"${LKM_PATH}\" 2>/dev/null`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKMNAMES_PATH_MISSING "${LKM_PATH}" | |
| else | |
| # | |
| # Reformat the LKM names so we only need to do it once. | |
| # | |
| LKM_NAMES="" | |
| for RKHTMPVAR in ${LKM_BADNAMES}; do | |
| RKHTMPVAR=`echo ${RKHTMPVAR} | sed -e 's/\./\\\./g'` | |
| LKM_NAMES="${LKM_NAMES} ${RKHTMPVAR}" | |
| done | |
| get_temp_file "${RKHTMPDIR}/modslist" | |
| ${FIND_CMD} "${LKM_PATH}" -type f -a \( -name "*.o" -o -name "*.ko" -o -name "*.ko.xz" \) >"${TEMPFILE}" 2>/dev/null | |
| for RKHTMPVAR in ${LKM_NAMES}; do | |
| if [ -n "`grep -E \"/${RKHTMPVAR}(\.xz)?$\" "${TEMPFILE}"`" ]; then | |
| FOUND=1 | |
| FOUNDFILES="${FOUNDFILES} ${RKHTMPVAR}" | |
| fi | |
| done | |
| rm -f "${TEMPFILE}" >/dev/null 2>&1 | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 4 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES | |
| for RKHTMPVAR in ${FOUNDFILES}; do | |
| RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/\\\././g'` | |
| display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKMNAMES_FOUND "${LKM_PATH}" "${RKHTMPVAR}" | |
| done | |
| fi | |
| fi | |
| return | |
| } | |
| linux_specific_checks() { | |
| # | |
| # This function performs tests specific to the Linux O/S. | |
| # | |
| linux_loaded_modules | |
| linux_avail_modules | |
| return | |
| } | |
| os_specific_checks() { | |
| # | |
| # This function performs any O/S specific tests. | |
| # | |
| if `check_test os_specific`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST os_specific | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST os_specific | |
| fi | |
| return | |
| fi | |
| # | |
| # Run the relevant O/S specific tests. | |
| # | |
| case "${OPERATING_SYSTEM}" in | |
| FreeBSD|NetBSD|DragonFly) | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --log-indent 2 ROOTKIT_OS_START "${OPERATING_SYSTEM}" | |
| bsd_specific_checks | |
| test "${OPERATING_SYSTEM}" = "FreeBSD" -o "${OPERATING_SYSTEM}" = "DragonFly" && freebsd_specific_checks | |
| ;; | |
| Linux) | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --log-indent 2 ROOTKIT_OS_START "${OPERATING_SYSTEM}" | |
| linux_specific_checks | |
| ;; | |
| *) | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color YELLOW --result SKIPPED --log-indent 2 ROOTKIT_OS_START "${OPERATING_SYSTEM}" | |
| display --to LOG --type INFO ROOTKIT_OS_SKIPPED | |
| ;; | |
| esac | |
| return | |
| } | |
| do_rootkit_checks() { | |
| # | |
| # This function carries out a sequence of tests for rootkits. | |
| # This consists of the default files and directories check, | |
| # possible rootkit checks, and checks for malware. | |
| # | |
| if `check_test rootkits`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST rootkits | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW CHECK_ROOTKITS | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST rootkits | |
| fi | |
| return | |
| fi | |
| rootkit_file_dir_checks | |
| check_test known_rkts || check_test all && keypresspause | |
| additional_rootkit_checks | |
| malware_checks | |
| trojan_checks | |
| os_specific_checks | |
| keypresspause | |
| return | |
| } | |
| check_port_wl() { | |
| # | |
| # This function tries to find the PID and command pathname using | |
| # a given port. It then checks to see if the port is whitelisted. | |
| # | |
| # A single parameter indicates if we are in the 'hidden_ports' | |
| # test or not. | |
| # | |
| PID=0 | |
| PID_SEEN=0 | |
| FNAME="" | |
| FOUND="" | |
| IN_HIDDEN_PORTS=$1 | |
| if [ -n "${LSOF_CMD}" ]; then | |
| IFS=$IFSNL | |
| for LSOFLINE in `${LSOF_CMD} -wnlP -i ${PROTO}:${PORT} 2>/dev/null`; do | |
| # | |
| # We must only look at connections using the port on the local host. | |
| # | |
| if [ -n "`echo \"${LSOFLINE}\" | grep \" ${PROTO} \*:${PORT} \"`" ]; then | |
| # Process listening for connections from anywhere. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| elif [ -n "`echo \"${LSOFLINE}\" | grep -E \" ${PROTO} [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:${PORT}[ -]\"`" ]; then | |
| # Established or listening process using IPv4 address. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| elif [ -n "`echo \"${LSOFLINE}\" | grep -E \" ${PROTO} \[[:0-9a-fA-F]+\]:${PORT}[ -]\"`" ]; then | |
| # Established or listening process using IPv6 address. | |
| PID=`echo "${LSOFLINE}" | ${AWK_CMD} '{ print $2 }'` | |
| else | |
| # Ignore anything else. | |
| continue | |
| fi | |
| PID_SEEN=1 | |
| # | |
| # Try and get the running process name. | |
| # | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| RKHTMPVAR="" | |
| if [ $SOL_PROC -eq 1 ]; then | |
| test -h "/proc/${PID}/path/a.out" && RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "/proc/${PID}/path/a.out"` | |
| elif [ $SUNOS -eq 0 -o -h "/proc/${PID}/exe" ]; then | |
| test -h "/proc/${PID}/exe" && RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "/proc/${PID}/exe"` | |
| fi | |
| test -n "${RKHTMPVAR}" && FNAME=`echo "${RKHTMPVAR}" | cut -d' ' -f1` | |
| fi | |
| if [ -z "${FNAME}" ]; then | |
| if [ $SUNOS -eq 1 ]; then | |
| FNAME=`${LSOF_CMD} -wnlP +c 0 -p $PID 2>/dev/null | grep '[ ]txt[ ][ ]*VREG[ ]' 2>/dev/null | head ${HEAD_OPT}1 | ${AWK_CMD} '{ print $NF }'` | |
| else | |
| FNAME=`${LSOF_CMD} -wnlP +c 0 -p $PID 2>/dev/null | grep '[ ]txt[ ][ ]*REG[ ]' | ${AWK_CMD} '{ print $NF }'` | |
| fi | |
| fi | |
| if [ -n "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| FOUND="${FNAME}" | |
| break | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| if [ -z "${FOUND}" -a $PID_SEEN -eq 1 ]; then | |
| FNAME="" | |
| FOUND="${PROTO}:${PORT}" | |
| fi | |
| elif [ $IN_HIDDEN_PORTS -eq 1 ]; then | |
| # The 'netstat' command offers us no further information | |
| # on hidden ports, so we can skip it. | |
| : | |
| else | |
| case "${OPERATING_SYSTEM}" in | |
| Linux) | |
| FOUND=`${NETSTAT_CMD} -an | grep -i "^${PROTO}.*:${PORT} " | ${AWK_CMD} '{ print $4 }' | grep ":${PORT}$"` | |
| ;; | |
| *BSD|Darwin|IRIX*|DragonFly) | |
| FOUND=`${NETSTAT_CMD} -an | grep -i "^${PROTO}.*\.${PORT} " | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| ;; | |
| AIX) | |
| if [ "${PROTO}" = "UDP" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | grep -i "^udp.*\.${PORT} " | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| elif [ "${PROTO}" = "TCP" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | grep -E -i "^tcp.*\.${PORT} .*(BOUND|ESTABLISH|LISTEN)" | ${AWK_CMD} '{ print $4 }' | grep "\.${PORT}$"` | |
| fi | |
| ;; | |
| SunOS) | |
| if [ "${PROTO}" = "UDP" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^UDP: IPv4/, /^$/ { print $1 }' | grep "\.${PORT}$"` | |
| if [ -z "${FOUND}" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^UDP: IPv6/, /^$/ { print $1 }' | grep "\.${PORT}$"` | |
| fi | |
| elif [ "${PROTO}" = "TCP" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv4/, /^$/ { print $0 }' | grep -E 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| if [ -z "${FOUND}" ]; then | |
| FOUND=`${NETSTAT_CMD} -an | ${AWK_CMD} '/^TCP: IPv6/, /^$/ { print $0 }' | grep -E 'BOUND|ESTABLISH|LISTEN' | ${AWK_CMD} '{ print $1 }' | grep "\.${PORT}$"` | |
| fi | |
| fi | |
| ;; | |
| esac | |
| fi | |
| # | |
| # If we have found something, then see if it is whitelisted. | |
| # | |
| if [ -n "${FOUND}" -o $IN_HIDDEN_PORTS -eq 1 ]; then | |
| RKHTMPVAR2=0 | |
| if [ -n "${LSOF_CMD}" ]; then | |
| if [ -n "${FNAME}" ]; then | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${PORT_WHITELIST}\" | grep \"^${FNAMEGREP}:${PROTO}:${PORT}$\"`" ]; then | |
| RKHTMPVAR2=1 | |
| FOUND="path_whitelisted" | |
| elif [ -n "`echo \"${PORT_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| RKHTMPVAR2=1 | |
| FOUND="path_whitelisted" | |
| elif [ $PORT_WHITELIST_ALL_TRUSTED -eq 1 ]; then | |
| test -n "${BASENAME_CMD}" && RKHTMPVAR=`${BASENAME_CMD} "${FNAME}"` || RKHTMPVAR=`echo "${FNAME}" | sed -e 's:^.*/::'` | |
| RKHTMPVAR=`IFS=$RKHIFS find_cmd ${RKHTMPVAR}` | |
| if [ "${RKHTMPVAR}" = "${FNAME}" ]; then | |
| RKHTMPVAR2=1 | |
| FOUND="trusted_whitelisted" | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ $RKHTMPVAR2 -eq 0 -a -n "`echo \"${PORT_WHITELIST}\" | grep \"^${PROTO}:${PORT}$\"`" ]; then | |
| FOUND="port_whitelisted" | |
| fi | |
| fi | |
| return | |
| } | |
| do_network_port_checks() { | |
| # | |
| # This function will check the network ports to see | |
| # if any known backdoor ports are being used. | |
| # | |
| if `check_test ports || check_test hidden_ports`; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --nl NETWORK_PORTS_START | |
| fi | |
| if `check_test ports`; then | |
| display --to LOG --type INFO STARTING_TEST ports | |
| display --to LOG --type PLAIN --log-indent 2 NETWORK_PORTS_BACKDOOR_LOG | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST ports | |
| fi | |
| return | |
| fi | |
| # | |
| # We must first check to see if we can perform this test. | |
| # | |
| if [ -z "${LSOF_CMD}" -a -z "${NETSTAT_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color YELLOW --result SKIPPED NETWORK_PORTS_BACKDOOR | |
| display --to LOG --type INFO TEST_SKIPPED_OS 'network port checks' 'lsof or netstat command required.' | |
| return | |
| fi | |
| # | |
| # Check that the backdoor ports data file is usable. | |
| # | |
| if [ ! -e "${DB_PATH}/backdoorports.dat" -o ! -s "${DB_PATH}/backdoorports.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color RED --result WARNING NETWORK_PORTS_BACKDOOR | |
| display --to LOG --type WARNING NETWORK_PORTS_FILE_MISSING "${DB_PATH}/backdoorports.dat" | |
| return | |
| elif [ ! -f "${DB_PATH}/backdoorports.dat" -o -h "${DB_PATH}/backdoorports.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color RED --result WARNING NETWORK_PORTS_BACKDOOR | |
| display --to LOG --type WARNING NETWORK_PORTS_FILE_NOTAFILE "${DB_PATH}/backdoorports.dat" | |
| return | |
| fi | |
| # | |
| # Next we do some further testing and the initial logging. | |
| # | |
| if [ -z "${LSOF_CMD}" ]; then | |
| case "${OPERATING_SYSTEM}" in | |
| *BSD|Linux|AIX|SunOS|Darwin|IRIX*|DragonFly) | |
| ;; | |
| *) | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color RED --result WARNING NETWORK_PORTS_BACKDOOR | |
| display --to LOG --type WARNING NETWORK_PORTS_UNKNOWN_NETSTAT | |
| return | |
| ;; | |
| esac | |
| fi | |
| if [ $PORT_WHITELIST_ALL_TRUSTED -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_PORTS_ENABLE_TRUSTED | |
| fi | |
| # | |
| # Now do the test. | |
| # | |
| FOUNDPORT=0 | |
| IFS=$IFSNL | |
| for LINE in `cat "${DB_PATH}/backdoorports.dat"`; do | |
| if [ -z "`echo \"${LINE}\" | grep '^[0-9][0-9]*:'`" ]; then | |
| continue | |
| fi | |
| PORT=`echo "${LINE}" | cut -d: -f1` | |
| DESCRIPTION=`echo "${LINE}" | cut -d: -f2` | |
| PROTO=`echo "${LINE}" | cut -d: -f3 | tr '[:lower:]' '[:upper:]'` | |
| ROOTKIT_COUNT=`expr $ROOTKIT_COUNT + 1` | |
| if [ -z "`echo \"${PORT}\" | grep '^[1-9][0-9]*$'`" ]; then | |
| echo "Error: Invalid port in backdoorports.dat file: $LINE" | |
| continue | |
| elif [ "${PROTO}" != "UDP" -a "${PROTO}" != "TCP" ]; then | |
| echo "Error: Invalid protocol in backdoorports.dat file: $LINE" | |
| continue | |
| fi | |
| check_port_wl 0 | |
| # We need to reset IFS because it is set in 'check_port_wl'. | |
| IFS=$IFSNL | |
| # | |
| # Now log the result. | |
| # | |
| case "${FOUND}" in | |
| path_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_PORTS_PATH_WHITELIST "${PROTO}" "${PORT}" "`name2text \"${FNAME}\"`" | |
| display --to LOG --type PLAIN --log-indent 4 --result WHITELISTED NETWORK_PORTS_BACKDOOR_CHK "${PROTO}" "${PORT}" | |
| fi | |
| ;; | |
| trusted_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_PORTS_TRUSTED_WHITELIST "${PROTO}" "${PORT}" "`name2text \"${FNAME}\"`" | |
| display --to LOG --type PLAIN --log-indent 4 --result WHITELISTED NETWORK_PORTS_BACKDOOR_CHK "${PROTO}" "${PORT}" | |
| fi | |
| ;; | |
| port_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_PORTS_PORT_WHITELIST "${PROTO}" "${PORT}" | |
| display --to LOG --type PLAIN --log-indent 4 --result WHITELISTED NETWORK_PORTS_BACKDOOR_CHK "${PROTO}" "${PORT}" | |
| fi | |
| ;; | |
| "") | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent 4 --result NOT_FOUND NETWORK_PORTS_BACKDOOR_CHK "${PROTO}" "${PORT}" | |
| fi | |
| ;; | |
| *) | |
| FOUNDPORT=1 | |
| ROOTKIT_FAILED_COUNT=`expr $ROOTKIT_FAILED_COUNT + 1` | |
| display --to LOG --type PLAIN --log-indent 4 --result FOUND NETWORK_PORTS_BACKDOOR_CHK "${PROTO}" "${PORT}" | |
| test -n "${FNAME}" && FNAME=" by `name2text \"${FNAME}\"`" | |
| display --to LOG --type WARNING NETWORK_PORTS_BKDOOR_FOUND "${PROTO}" "${PORT}" "${FNAME}" "${DESCRIPTION}" | |
| ;; | |
| esac | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Finally show the overall result on the screen. | |
| # | |
| if [ $FOUNDPORT -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color GREEN --result NONE_FOUND NETWORK_PORTS_BACKDOOR | |
| else | |
| display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --color RED --result WARNING NETWORK_PORTS_BACKDOOR | |
| fi | |
| return | |
| } | |
| do_network_hidden_port_checks() { | |
| # | |
| # This function will check the network | |
| # ports to see if any are being hidden. | |
| # | |
| if `check_test hidden_ports`; then | |
| display --to LOG --type INFO --nl STARTING_TEST hidden_ports | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST hidden_ports | |
| fi | |
| return | |
| fi | |
| # | |
| # We must first check to see if we can perform this test. | |
| # | |
| UNHIDETCP_CMD=`find_cmd unhide-tcp` | |
| if [ -n "${UNHIDETCP_CMD}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FOUND_CMD 'unhide-tcp' "${UNHIDETCP_CMD} ${UNHIDETCP_OPTS}" | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 NETWORK_HIDDEN_PORTS | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NOT_FOUND_CMD 'unhide-tcp' | |
| fi | |
| return | |
| fi | |
| if [ $SUNOS -eq 1 ]; then | |
| if [ "${AWK_CMD}" = "awk" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 NETWORK_HIDDEN_PORTS | |
| display --to LOG --type INFO NOT_FOUND_CMD 'gawk or nawk' | |
| return | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FOUND_CMD 'awk' "${AWK_CMD}" | |
| fi | |
| fi | |
| # | |
| # We don't *need* the 'lsof' command to perform this test, but | |
| # if it is available then it will be used to find out pathnames. | |
| # | |
| if [ $PORT_WHITELIST_ALL_TRUSTED -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_PORTS_ENABLE_TRUSTED | |
| fi | |
| # | |
| # Now perform the test. We must do this in two parts | |
| # to pick out the TCP ports, and then the UDP ports. | |
| # | |
| RKHTMPVAR=`${UNHIDETCP_CMD} ${UNHIDETCP_OPTS} 2>&1` | |
| TCP_PORTS=`echo "${RKHTMPVAR}" | ${AWK_CMD} '/^(\[\*\])?Starting TCP check/, /^(\[\*\])?Starting UDP check/ { print $0 }' | grep '^Found ' | cut -d: -f2` | |
| UDP_PORTS=`echo "${RKHTMPVAR}" | ${AWK_CMD} '/^(\[\*\])?Starting UDP check/, 0 { print $0 }' | grep '^Found ' | cut -d: -f2` | |
| if [ -z "${TCP_PORTS}" -a -z "${UDP_PORTS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 NETWORK_HIDDEN_PORTS | |
| else | |
| FOUND_PORTS="" | |
| for PROTO in TCP UDP; do | |
| HIDDEN_PORTS=`eval echo "\\$${PROTO}_PORTS"` | |
| test -z "${HIDDEN_PORTS}" && continue | |
| HIDDEN_PORTS=`echo ${HIDDEN_PORTS} | tr ' ' '\n' | sort | uniq` | |
| HIDDEN_PORTS=`echo ${HIDDEN_PORTS}` | |
| for PORT in ${HIDDEN_PORTS}; do | |
| check_port_wl 1 | |
| # | |
| # Now log the result. | |
| # | |
| case "${FOUND}" in | |
| path_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_HIDDEN_PORTS_PATH_WHITELIST "${PROTO}" "${PORT}" "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| trusted_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_HIDDEN_PORTS_TRUSTED_WHITELIST "${PROTO}" "${PORT}" "`name2text \"${FNAME}\"`" | |
| fi | |
| ;; | |
| port_whitelisted) | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO NETWORK_HIDDEN_PORTS_PORT_WHITELIST "${PROTO}" "${PORT}" | |
| fi | |
| ;; | |
| *) | |
| FOUND_PORTS="${FOUND_PORTS} | |
| ${PROTO}:${PORT}:${FNAME}" | |
| ;; | |
| esac | |
| done | |
| done | |
| if [ -z "${FOUND_PORTS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 NETWORK_HIDDEN_PORTS | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 NETWORK_HIDDEN_PORTS | |
| display --to LOG --type WARNING --log-indent 2 NETWORK_HIDDEN_PORTS_FOUND | |
| IFS=$IFSNL | |
| FOUND_PORTS=`echo "${FOUND_PORTS}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FOUND_PORTS}; do | |
| PROTO=`echo ${RKHTMPVAR} | cut -d: -f1` | |
| PORT=`echo ${RKHTMPVAR} | cut -d: -f2` | |
| FNAME=`echo ${RKHTMPVAR} | cut -d: -f3-` | |
| if [ -z "${FNAME}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 NETWORK_HIDDEN_PORTS_CHK "${PROTO}" "${PORT}" | |
| else | |
| display --to LOG --type PLAIN --log-indent 9 NETWORK_HIDDEN_PORTS_CHK_NAME "${PROTO}" "${PORT}" "`name2text \"${FNAME}\"`" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| return | |
| } | |
| do_network_interface_checks() { | |
| # | |
| # This function will check the network interfaces to see | |
| # if any are in promiscuous mode. It will also check to see | |
| # if there are any applications running which are capturing | |
| # network interface packets. | |
| # | |
| if `check_test promisc || check_test packet_cap_apps`; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 --nl NETWORK_INTERFACE_START | |
| fi | |
| if `check_test promisc`; then | |
| display --to LOG --type INFO STARTING_TEST promisc | |
| if [ -n "${IFCONFIG_CMD}" -o \( $LINUXOS -eq 1 -a -n "${IP_CMD}" \) ]; then | |
| PROMISCSCAN1="" | |
| PROMISCSCAN2="" | |
| if [ -n "${IFCONFIG_CMD}" ]; then | |
| if [ -n "${IFWLIST}" ]; then | |
| IFWLIST=`echo ${IFWLIST}` | |
| display --to LOG --type INFO NETWORK_PROMISC_WLIST "${IFWLIST}" | |
| IFWLIST=`echo ${IFWLIST} | tr ' ' '|'` | |
| fi | |
| case "${OPERATING_SYSTEM}" in | |
| *BSD|DragonFly) | |
| if [ -z "${IFWLIST}" ]; then | |
| PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | ${AWK_CMD} '$1 !~ /^pflog/ && /PROMISC/ { print }'` | |
| else | |
| PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | ${AWK_CMD} '$1 !~ /^pflog/ && $1 !~ /^('${IFWLIST}'):$/ && /PROMISC/ { print }'` | |
| fi | |
| ;; | |
| SunOS|IRIX*|AIX) | |
| if [ -z "${IFWLIST}" ]; then | |
| PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | ${AWK_CMD} '/PROMISC/ { print }'` | |
| else | |
| PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | ${AWK_CMD} '$1 !~ /^('${IFWLIST}'):$/ && /PROMISC/ { print }'` | |
| fi | |
| ;; | |
| *) | |
| if [ -z "${IFWLIST}" ]; then | |
| PROMISCSCAN1=`${IFCONFIG_CMD} 2>&1 | ${AWK_CMD} 'BEGIN { RS="" }; /PROMISC/ { print }'` | |
| else | |
| PROMISCSCAN1=`${IFCONFIG_CMD} 2>&1 | ${AWK_CMD} 'BEGIN { RS="" }; $1 !~ /^('${IFWLIST}'):?$/ && /PROMISC/ { print }'` | |
| fi | |
| ;; | |
| esac | |
| else | |
| display --to LOG --type INFO NETWORK_PROMISC_NO_CMD ifconfig ip | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ifconfig '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ifconfig' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ifconfig' | |
| fi | |
| fi | |
| if [ $LINUXOS -eq 1 ]; then | |
| if [ -n "${IP_CMD}" ]; then | |
| PROMISCSCAN2=`${IP_CMD} link | grep '^[0-9]' | grep -vE "^[0-9][0-9]*: (${IFWLIST}):" | grep 'PROMISC'` | |
| else | |
| display --to LOG --type INFO NETWORK_PROMISC_NO_CMD ip ifconfig | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ip '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ip' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ip' | |
| fi | |
| fi | |
| fi | |
| # | |
| # Now show the results of the interface check. | |
| # | |
| if [ -z "${PROMISCSCAN1}" -a -z "${PROMISCSCAN2}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 NETWORK_PROMISC_CHECK | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PROMISC_CHECK | |
| display --to LOG --type WARNING NETWORK_PROMISC_IF | |
| if [ -n "${PROMISCSCAN1}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 NETWORK_PROMISC_IF_1 | |
| PROMISCSCAN1=`echo "${PROMISCSCAN1}" | ${AWK_CMD} '$0 !~ /^ / || /PROMISC/ { print }'` | |
| IFS=$IFSNL | |
| for IFACE in ${PROMISCSCAN1}; do | |
| display --to LOG --type PLAIN --log-indent 13 NAME "${IFACE}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ -n "${PROMISCSCAN2}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 NETWORK_PROMISC_IF_2 | |
| PROMISCSCAN2=`echo "${PROMISCSCAN2}" | cut -d: -f2-` | |
| IFS=$IFSNL | |
| # Only indent by 12 spaces here because the output starts with a space. | |
| for IFACE in ${PROMISCSCAN2}; do | |
| display --to LOG --type PLAIN --log-indent 12 NAME "${IFACE}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --result SKIPPED --screen-indent 4 NETWORK_PROMISC_CHECK | |
| display --to LOG --type INFO NETWORK_PROMISC_NO_IFCONF_IP | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ifconfig '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ifconfig' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ifconfig' | |
| fi | |
| if [ $LINUXOS -eq 1 ]; then | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ip '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ip' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ip' | |
| fi | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST promisc | |
| fi | |
| # | |
| # For the packet capturing check, we must first see if we | |
| # are able to run the test. We let the user know if the test | |
| # was disabled, or if the lsof command is not present. | |
| # | |
| if `check_test packet_cap_apps`; then | |
| display --to LOG --type INFO --nl STARTING_TEST packet_cap_apps | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST packet_cap_apps | |
| fi | |
| return | |
| fi | |
| if [ $LINUXOS -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --result SKIPPED --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK | |
| display --to LOG --type INFO TEST_SKIPPED_OS 'packet_cap_apps' '/proc/net/packet required.' | |
| return | |
| elif [ ! -f "/proc/net/packet" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK | |
| display --to LOG --type WARNING NETWORK_PACKET_CAP_CHECK_NO_FILE '/proc/net/packet' | |
| return | |
| elif [ -z "${LSOF_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --result SKIPPED --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' lsof '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'lsof' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'lsof' | |
| fi | |
| return | |
| fi | |
| # | |
| # Now run the test. | |
| # | |
| FOUND=0 | |
| WHITEPROC="" | |
| BLACKPROC="" | |
| LIBPCAPRES=`grep -E -v '(^sk | 888e )' /proc/net/packet 2>/dev/null | head ${HEAD_OPT}1` | |
| if [ -n "${LIBPCAPRES}" ]; then | |
| ALLOWPROCLISTENERS="" | |
| # | |
| # We expand the whitelist option here to ensure | |
| # that any wildcard entries are the most recent. | |
| # | |
| if [ -n "${ALLOWPROCLIST_OPT}" ]; then | |
| ALLOWPROCLISTENERS=`expand_paths ALLOWPROCLIST_OPT` | |
| fi | |
| INODE_LIST="" | |
| for INODE in `grep -E -v '(^sk | 888e )' /proc/net/packet | ${AWK_CMD} '{ print $9 }'`; do | |
| INODE_LIST="${INODE_LIST}|$INODE" | |
| done | |
| INODE_LIST=`echo "${INODE_LIST}" | sed -e 's/^|//'` | |
| test -z "${INODE_LIST}" && INODE_LIST="RKHunterPktCapture" | |
| for PID in `${LSOF_CMD} -lMnPw -d 1-20 2>/dev/null | grep -E "[ ](pack[ ]+(${INODE_LIST})|sock[ ]+[^ ]+[ ]+[^ ]+[ ]+(${INODE_LIST}))[ ]" | ${AWK_CMD} '{ print $2 }'`; do | |
| NAME="" | |
| if [ -h "/proc/$PID/exe" -a $HAVE_READLINK -eq 1 ]; then | |
| NAME=`${READLINK_CMD} ${READLINK_OPT} "/proc/$PID/exe" | cut -d' ' -f1` | |
| elif [ -f "/proc/$PID/status" ]; then | |
| NAME=`grep '^Name:.' /proc/$PID/status | sed -e 's/^Name:.//'` | |
| fi | |
| test -z "${NAME}" && continue | |
| FNAMEGREP=`echo "${NAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${ALLOWPROCLISTENERS}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ -z "`echo \"${WHITEPROC}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| WHITEPROC="${WHITEPROC} | |
| ${NAME}" | |
| fi | |
| else | |
| FOUND=1 | |
| BLACKPROC="${BLACKPROC} | |
| ${PID}:${NAME}" | |
| fi | |
| done | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${BLACKPROC}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| PID=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| NAME=`echo "${RKHTMPVAR}" | cut -d: -f2-` | |
| display --to LOG --type WARNING NETWORK_PACKET_CAP_FOUND "`name2text \"${NAME}\"`" "${PID}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Log any whitelisted entries. | |
| # | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| IFS=$IFSNL | |
| for NAME in ${WHITEPROC}; do | |
| test -z "${NAME}" && continue | |
| display --to LOG --type INFO NETWORK_PACKET_CAP_WL "`name2text \"${NAME}\"`" | |
| done | |
| fi | |
| IFS=$RKHIFS | |
| return | |
| } | |
| do_network_checks() { | |
| # | |
| # This function carries out some network checks. This consists | |
| # of port checks, and some interface checks. | |
| # | |
| if `check_test network`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST network | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW CHECK_NETWORK | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST network | |
| fi | |
| return | |
| fi | |
| do_network_port_checks | |
| do_network_hidden_port_checks | |
| do_network_interface_checks | |
| return | |
| } | |
| do_system_startup_file_checks() { | |
| # | |
| # This function carries out checks on the system startup files. | |
| # | |
| if `check_test startup_files`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST startup_files | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 STARTUP_FILES_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST startup_files | |
| fi | |
| return | |
| fi | |
| # | |
| # First we check that the local host name has been set. | |
| # | |
| if [ -n "${HOST_NAME}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 STARTUP_HOSTNAME | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_HOSTNAME | |
| display --to LOG --type WARNING STARTUP_NO_HOSTNAME | |
| fi | |
| # | |
| # Check that the startup file malware checks are to be done. | |
| # | |
| if `check_test startup_malware`; then | |
| display --to LOG --type INFO --nl STARTING_TEST startup_malware | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST startup_malware | |
| fi | |
| return | |
| fi | |
| # | |
| # First check to see that we can run the test. | |
| # | |
| if [ "${STARTUP_PATHS}" = "NONE" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result SKIPPED --log-indent 2 --screen-indent 4 STARTUP_CHECK_FILES_EXIST | |
| display --to LOG --type INFO STARTUP_NONE_GIVEN | |
| return | |
| fi | |
| # | |
| # Now get and check that the system startup files are okay. | |
| # | |
| get_rc_paths | |
| if [ -n "${RC_PATHS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 STARTUP_CHECK_FILES_EXIST | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_CHECK_FILES_EXIST | |
| display --to LOG --type WARNING STARTUP_CHECK_NO_RC_FILES | |
| return | |
| fi | |
| # | |
| # Next we check all the startup files for any suspicious | |
| # strings in them. | |
| # | |
| FOUND=0 | |
| FOUNDSTRINGS="" | |
| # | |
| # Since we are going to be checking a lot of files | |
| # for strings that are static, we may as well do | |
| # some pre-processing of the string, and then we | |
| # only need to spend time if a string is found. | |
| # | |
| RCSTRINGS="" | |
| ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1` | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${RCLOCAL_STRINGS}; do | |
| RKHTMPVAR=`echo ${RKHTMPVAR} | sed -e 's/^[ ]*//'` | |
| STRING=`echo ${RKHTMPVAR} | cut -d: -f1 | sed -e 's/\./\\\./g'` | |
| INFO=`echo ${RKHTMPVAR} | cut -d: -f2` | |
| RCSTRINGS="${RCSTRINGS} | |
| ${STRING}:${INFO}" | |
| done | |
| IFS=$RKHIFS | |
| RCSTRINGS=`echo "${RCSTRINGS}" | sed -e '/^$/d'` | |
| for FNAME in ${RC_PATHS}; do | |
| IFS=$IFSNL | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| for STR in ${RCSTRINGS}; do | |
| STRING=`echo ${STR} | cut -d: -f1` | |
| RKHTMPVAR=`grep "${STRING}" "${FNAME}"` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| test -z "`echo \"${RKHTMPVAR}\" | grep -E -v '^[ ]*#'`" && continue | |
| if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:${STRING}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| STRING=`echo ${STRING} | sed -e 's/\\\//g'` | |
| display --to LOG --type INFO FILE_PROP_WL_STR "`name2text \"${FNAME}\"`" "${STRING}" 'startup_malware' | |
| fi | |
| elif [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}$\"`" -a -z "`echo \"${RTKT_FILE_WHITELIST}\" | grep \"^${FNAMEGREP}:$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_WL "`name2text \"${FNAME}\"`" 'startup_malware' | |
| fi | |
| else | |
| FOUND=1 | |
| STRING=`echo ${STRING} | sed -e 's/\\\//g'` | |
| INFO=`echo ${STR} | cut -d: -f2` | |
| FOUNDSTRINGS="${FOUNDSTRINGS} | |
| ${FNAME}:${STRING}:${INFO}" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| done | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 STARTUP_CHECK_FILES_MALWARE | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1` | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_CHECK_FILES_MALWARE | |
| IFS=$IFSNL | |
| FOUNDSTRINGS=`echo "${FOUNDSTRINGS}" | sed -e '/^$/d'` | |
| for RKHTMPVAR in ${FOUNDSTRINGS}; do | |
| FNAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| STRING=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| INFO=`echo "${RKHTMPVAR}" | cut -d: -f3` | |
| display --to LOG --type WARNING ROOTKIT_POSS_STRINGS_FOUND "${STRING}" "`name2text \"${FNAME}\"`" "${INFO}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| return | |
| } | |
| pwdgrp_changes() { | |
| # | |
| # This function checks the changes made to the passwd and group files. | |
| # | |
| FNAME=$1 | |
| LINES=$2 | |
| SEEN_IDS="" | |
| IFS=$IFSNL | |
| for LINE in ${LINES}; do | |
| # | |
| # First we need to check if we have already dealt with | |
| # this id. If we have, then just get the next line. | |
| # | |
| PWDGRPID=`echo "${LINE}" | cut -d: -f1 | cut -c3-` | |
| IDGREP=`echo "${PWDGRPID}" | sed -e 's/\./\\\./g'` | |
| RKHTMPVAR=`echo "${SEEN_IDS}" | grep " ${IDGREP} "` | |
| test -n "${RKHTMPVAR}" && continue | |
| # | |
| # This id hasn't been seen before, so we record it. | |
| # | |
| SEEN_IDS="${SEEN_IDS} ${PWDGRPID} " | |
| # | |
| # Next we see if the id has just been added or removed. | |
| # To do this we simply see if it appears more than once. | |
| # | |
| RKHTMPVAR=`echo "${LINES}" | grep "^> ${IDGREP}:"` | |
| RKHTMPVAR2=`echo "${LINES}" | grep "^< ${IDGREP}:"` | |
| if [ \( -n "${RKHTMPVAR}" -a -z "${RKHTMPVAR2}" \) -o \( -z "${RKHTMPVAR}" -a -n "${RKHTMPVAR2}" \) ]; then | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| if [ "${FNAME}" = "passwd" ]; then | |
| display --to LOG --type WARNING --log-indent 4 PWD_CHANGES_IDREM "${PWDGRPID}" | |
| else | |
| display --to LOG --type WARNING --log-indent 4 GROUP_CHANGES_IDREM "${PWDGRPID}" | |
| fi | |
| else | |
| if [ "${FNAME}" = "passwd" ]; then | |
| display --to LOG --type WARNING --log-indent 4 PWD_CHANGES_IDADD "${PWDGRPID}" | |
| else | |
| display --to LOG --type WARNING --log-indent 4 GROUP_CHANGES_IDADD "${PWDGRPID}" | |
| fi | |
| fi | |
| continue | |
| fi | |
| # | |
| # The id has changed in some way. We now need to | |
| # go through the fields and see what has changed. | |
| # | |
| FIELD_IDX=1 | |
| OLD_LINE=`echo "${RKHTMPVAR}" | cut -d: -f2-` | |
| NEW_LINE=`echo "${RKHTMPVAR2}" | cut -d: -f2-` | |
| STR=${OLD_LINE} | |
| if [ "${FNAME}" = "passwd" ]; then | |
| display --to LOG --type WARNING PWD_CHANGES_FOUND "${PWDGRPID}" | |
| else | |
| display --to LOG --type WARNING GROUP_CHANGES_FOUND "${PWDGRPID}" | |
| fi | |
| while test -n "${STR}"; do | |
| OLD_FIELD=`echo "${OLD_LINE}" | cut -d: -f$FIELD_IDX` | |
| NEW_FIELD=`echo "${NEW_LINE}" | cut -d: -f$FIELD_IDX` | |
| if [ "${OLD_FIELD}" != "${NEW_FIELD}" ]; then | |
| if [ "${FNAME}" = "passwd" ]; then | |
| case $FIELD_IDX in | |
| 1) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_PWD "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 2) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_UID "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 3) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_GID "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 4) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_COMM "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 5) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_HOME "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 6) | |
| display --to LOG --type PLAIN --log-indent 9 PWD_CHANGES_SHL "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| *) | |
| display --to LOG --type PLAIN --log-indent 9 PWDGRP_CHANGES_UNK "${FNAME}" "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| esac | |
| else | |
| case $FIELD_IDX in | |
| 1) | |
| display --to LOG --type PLAIN --log-indent 9 GROUP_CHANGES_PWD "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 2) | |
| display --to LOG --type PLAIN --log-indent 9 GROUP_CHANGES_GID "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| 3) | |
| OLD_GRPUSRS=" `echo ${OLD_FIELD} | tr ',' ' '` " | |
| NEW_GRPUSRS=" `echo ${NEW_FIELD} | tr ',' ' '` " | |
| IFS=$RKHIFS | |
| for GRPUSR in ${OLD_GRPUSRS} ${NEW_GRPUSRS}; do | |
| RKHTMPVAR=`echo ${GRPUSR} | sed -e 's/\./\\\./g'` | |
| RKHTMPVAR2=`echo "${OLD_GRPUSRS}" | grep " ${RKHTMPVAR} "` | |
| RKHTMPVAR3=`echo "${NEW_GRPUSRS}" | grep " ${RKHTMPVAR} "` | |
| if [ -n "${RKHTMPVAR2}" -a -z "${RKHTMPVAR3}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 GROUP_CHANGES_GRPREM "${GRPUSR}" | |
| elif [ -z "${RKHTMPVAR2}" -a -n "${RKHTMPVAR3}" ]; then | |
| display --to LOG --type PLAIN --log-indent 9 GROUP_CHANGES_GRPADD "${GRPUSR}" | |
| fi | |
| done | |
| IFS=$IFSNL | |
| ;; | |
| *) | |
| display --to LOG --type PLAIN --log-indent 9 PWDGRP_CHANGES_UNK "${FNAME}" "${OLD_FIELD}" "${NEW_FIELD}" | |
| ;; | |
| esac | |
| fi | |
| fi | |
| FIELD_IDX=`expr $FIELD_IDX + 1` | |
| RKHTMPVAR=`echo "${STR}" | cut -d: -f2-` | |
| # | |
| # For the group file the last field may be | |
| # empty, so we need to cater for this. | |
| # | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| if [ \( "${FNAME}" = "passwd" -a $FIELD_IDX -eq 6 \) -o \( "${FNAME}" = "group" -a $FIELD_IDX -eq 3 \) ]; then | |
| STR="" | |
| RKHTMPVAR="x" | |
| fi | |
| fi | |
| test "${RKHTMPVAR}" = "${STR}" && STR="" || STR=${RKHTMPVAR} | |
| done | |
| done | |
| IFS=$RKHIFS | |
| return | |
| } | |
| do_group_accounts_check() { | |
| # | |
| # This function carries out checks on the /etc/passwd and | |
| # /etc/group files. | |
| # | |
| if `check_test group_accounts`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST group_accounts | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 ACCOUNTS_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST group_accounts | |
| fi | |
| return | |
| fi | |
| # | |
| # First check that /etc/passwd exists. | |
| # | |
| if [ -s "/etc/passwd" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 ACCOUNTS_PWD_FILE_CHECK | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ACCOUNTS_FOUND_PWD_FILE '/etc/passwd' | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 ACCOUNTS_PWD_FILE_CHECK | |
| display --to LOG --type WARNING ACCOUNTS_NO_PWD_FILE '/etc/passwd' | |
| fi | |
| # | |
| # Next, check for root equivalent accounts. These will have | |
| # a UID of zero. | |
| # | |
| if [ -s "/etc/passwd" ]; then | |
| UID_LIST="" | |
| RKHTMPVAR2="" | |
| if [ $MACOSX -eq 1 ]; then | |
| DSCL_CMD=`find_cmd dscl` | |
| if [ -n "${DSCL_CMD}" ]; then | |
| display --to LOG --type INFO FOUND_CMD 'dscl' "${DSCL_CMD}" | |
| RKHTMPVAR2=`${DSCL_CMD} . search /Users uid 0 | grep -E '^[^ )]' | cut -d' ' -f1` | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'dscl' | |
| fi | |
| fi | |
| IFS=$IFSNL | |
| for RKHTMPVAR in `grep '^[^:]*:[^:]*:0:' /etc/passwd | cut -d: -f1` ${RKHTMPVAR2}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| test "${RKHTMPVAR}" = "root" && continue | |
| RKHUSERID=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'` | |
| # | |
| # We will ignore any whitelisted UID 0 accounts. | |
| # | |
| if [ -z "`echo \"${UID0_WHITELIST}\" | grep \" ${RKHUSERID} \"`" ]; then | |
| UID_LIST="${UID_LIST} | |
| ${RKHTMPVAR}" | |
| else | |
| display --to LOG --type INFO ACCOUNTS_UID0_WL "${RKHTMPVAR}" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${UID_LIST}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ACCOUNTS_UID0 | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ACCOUNTS_UID0 | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${UID_LIST}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| display --to LOG --type WARNING ACCOUNTS_UID0_FOUND "${RKHTMPVAR}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ACCOUNTS_UID0 | |
| display --to LOG --type INFO ACCOUNTS_NO_PWD_FILE '/etc/passwd' | |
| fi | |
| # | |
| # Now check for any passwordless accounts. We do this in two steps. | |
| # The first is to check the shadow file, and for TCB shadow files we | |
| # have to loop through all the shadow files in the /etc/tcb directory. | |
| # Then we check the /etc/passwd file for any passwordless accounts. | |
| # Finally we display the overall result. We ignore any whitelisted | |
| # passwordless accounts. | |
| # | |
| WL_SEEN="" | |
| PWD_PWDLESS_LIST="" | |
| SHAD_PWDLESS_LIST="" | |
| # | |
| # Check for passwordless accounts in the shadow file(s). | |
| # | |
| if [ -n "${SHADOW_FILE}" -o $HAVE_TCB_SHADOW -eq 1 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ -n "${SHADOW_FILE}" ]; then | |
| display --to LOG --type INFO ACCOUNTS_SHADOW_FILE "${SHADOW_FILE}" | |
| else | |
| display --to LOG --type INFO ACCOUNTS_SHADOW_TCB '/etc/tcb' | |
| fi | |
| fi | |
| # | |
| # We have do a bit of a kludge here. We need a loop in order to | |
| # cater for TCB shadow files in /etc/tcb. But at the same time | |
| # we only want to execute the loop once for non-TCB systems. To | |
| # do this we loop through either /etc or /etc/tcb. However, for | |
| # /etc we only execute the loop once because the grep statement | |
| # will have the exact shadow filename in SHADOW_FILE. For TCB | |
| # systems, SHADOW_FILE is set for each individual shadow file as | |
| # it pass round the loop. | |
| # | |
| if [ $HAVE_TCB_SHADOW -eq 1 ]; then | |
| RKHTMPVAR2="/etc/tcb" | |
| else | |
| RKHTMPVAR2="/etc" | |
| fi | |
| IFS=$IFSNL | |
| for DIR in ${RKHTMPVAR2}/*; do | |
| if [ $HAVE_TCB_SHADOW -eq 1 ]; then | |
| if [ -f "${DIR}/shadow" ]; then | |
| SHADOW_FILE="${DIR}/shadow" | |
| else | |
| continue | |
| fi | |
| fi | |
| for RKHTMPVAR in `grep '^[^:]*::' "${SHADOW_FILE}" | cut -d: -f1`; do | |
| # Ignore any NIS/YP entries | |
| test "${RKHTMPVAR}" = "+" && continue | |
| RKHUSERID=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'` | |
| if [ -z "`echo \"${PWD_WHITELIST}\" | grep \" ${RKHUSERID} \"`" ]; then | |
| SHAD_PWDLESS_LIST="${SHAD_PWDLESS_LIST} | |
| ${RKHTMPVAR}" | |
| test $HAVE_TCB_SHADOW -eq 1 && SHAD_PWDLESS_LIST="${SHAD_PWDLESS_LIST} (${SHADOW_FILE})" | |
| else | |
| WL_SEEN="${WL_SEEN} ${RKHTMPVAR} " | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ACCOUNTS_PWDLESS_WL "${RKHTMPVAR}" | |
| fi | |
| fi | |
| done | |
| test $HAVE_TCB_SHADOW -eq 0 && break | |
| done | |
| IFS=$RKHIFS | |
| else | |
| # | |
| # No shadow file found. | |
| # | |
| SHAD_PWDLESS_LIST="RKH:No shadow file" | |
| fi | |
| # | |
| # Check for passwordless accounts in /etc/passwd. | |
| # | |
| if [ -s "/etc/passwd" ]; then | |
| IFS=$IFSNL | |
| for RKHTMPVAR in `grep '^[^:]*::' /etc/passwd | cut -d: -f1`; do | |
| # Ignore any NIS/YP entries | |
| test "${RKHTMPVAR}" = "+" && continue | |
| RKHUSERID=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'` | |
| if [ -z "`echo \"${PWD_WHITELIST}\" | grep \" ${RKHUSERID} \"`" ]; then | |
| PWD_PWDLESS_LIST="${PWD_PWDLESS_LIST} | |
| ${RKHTMPVAR}" | |
| elif [ -z "`echo \"${WL_SEEN}\" | grep \" ${RKHUSERID} \"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO ACCOUNTS_PWDLESS_WL "${RKHTMPVAR}" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${SHAD_PWDLESS_LIST}" -a -z "${PWD_PWDLESS_LIST}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 ACCOUNTS_PWDLESS | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 ACCOUNTS_PWDLESS | |
| # | |
| # Log the shadow file results. | |
| # | |
| if [ "${SHAD_PWDLESS_LIST}" = "RKH:No shadow file" ]; then | |
| display --to LOG --type WARNING ACCOUNTS_NO_SHADOW_FILE | |
| else | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${SHAD_PWDLESS_LIST}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| display --to LOG --type WARNING ACCOUNTS_PWDLESS_FOUND 'shadow' "${RKHTMPVAR}" | |
| done | |
| fi | |
| # | |
| # Log the passwd file results. | |
| # | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${PWD_PWDLESS_LIST}; do | |
| test -z "${RKHTMPVAR}" && continue | |
| display --to LOG --type WARNING ACCOUNTS_PWDLESS_FOUND 'passwd' "${RKHTMPVAR}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Now we check for any changes that have occurred to the passwd | |
| # file since rkhunter was last run. | |
| # | |
| DIFF_CMD=`find_cmd diff` | |
| if `check_test passwd_changes`; then | |
| RKHTMPVAR=0 | |
| display --to LOG --type INFO --nl STARTING_TEST passwd_changes | |
| else | |
| RKHTMPVAR=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST passwd_changes | |
| fi | |
| fi | |
| if [ $RKHTMPVAR -eq 1 ]; then | |
| : | |
| elif [ ! -f "/etc/passwd" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 PASSWD_CHANGES | |
| display --to LOG --type INFO ACCOUNTS_NO_PWD_FILE '/etc/passwd' | |
| elif [ -z "${DIFF_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 PASSWD_CHANGES | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' diff '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'diff' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'diff' | |
| fi | |
| cp -f -p /etc/passwd "${RKHTMPDIR}/passwd" | |
| elif [ ! -f "${RKHTMPDIR}/passwd" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 PASSWD_CHANGES | |
| display --to LOG --type WARNING PASSWD_CHANGES_NO_TMP | |
| cp -f -p /etc/passwd "${RKHTMPDIR}/passwd" | |
| else | |
| DIFFS=`${DIFF_CMD} /etc/passwd "${RKHTMPDIR}/passwd" 2>/dev/null | grep '^[<>]'` | |
| if [ -z "${DIFFS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 PASSWD_CHANGES | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 PASSWD_CHANGES | |
| pwdgrp_changes "passwd" "${DIFFS}" | |
| # | |
| # Finally, move the current copy of the passwd file out | |
| # of the way, and take a new copy of the passwd file. | |
| # This allows the user to look back to see what the | |
| # last changes were, even if RKH is run again. | |
| # | |
| mv -f "${RKHTMPDIR}/passwd" "${RKHTMPDIR}/passwd.old" >/dev/null 2>&1 | |
| cp -f -p /etc/passwd "${RKHTMPDIR}/passwd" | |
| fi | |
| fi | |
| test -f "${RKHTMPDIR}/passwd" && chmod 600 "${RKHTMPDIR}/passwd" | |
| # | |
| # Next check for any changes that have occurred to the group | |
| # file since rkhunter was last run. | |
| # | |
| if `check_test group_changes`; then | |
| RKHTMPVAR=0 | |
| display --to LOG --type INFO --nl STARTING_TEST group_changes | |
| else | |
| RKHTMPVAR=1 | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST group_changes | |
| fi | |
| fi | |
| if [ $RKHTMPVAR -eq 1 ]; then | |
| : | |
| elif [ ! -f "/etc/group" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 GROUP_CHANGES | |
| display --to LOG --type WARNING GROUP_CHANGES_NO_FILE '/etc/group' | |
| elif [ -z "${DIFF_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 GROUP_CHANGES | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' diff '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'diff' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'diff' | |
| fi | |
| cp -f -p /etc/group "${RKHTMPDIR}/group" | |
| elif [ ! -f "${RKHTMPDIR}/group" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 GROUP_CHANGES | |
| display --to LOG --type WARNING GROUP_CHANGES_NO_TMP | |
| cp -f -p /etc/group "${RKHTMPDIR}/group" | |
| else | |
| DIFFS=`${DIFF_CMD} /etc/group "${RKHTMPDIR}/group" 2>/dev/null | grep '^[<>]'` | |
| if [ -z "${DIFFS}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 GROUP_CHANGES | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 GROUP_CHANGES | |
| pwdgrp_changes "group" "${DIFFS}" | |
| # | |
| # Finally, move the current copy of the group file out | |
| # of the way, and take a new copy of the group file. | |
| # This allows the user to look back to see what the | |
| # last changes were, even if RKH is run again. | |
| # | |
| mv -f "${RKHTMPDIR}/group" "${RKHTMPDIR}/group.old" >/dev/null 2>&1 | |
| cp -f -p /etc/group "${RKHTMPDIR}/group" | |
| fi | |
| fi | |
| test -f "${RKHTMPDIR}/group" && chmod 600 "${RKHTMPDIR}/group" | |
| # | |
| # Finally we do a check on the root account shell history files. | |
| # We check for bash, Korn, C-shell and zsh history files. | |
| # | |
| FOUND=0 | |
| FOUNDFILES="" | |
| if [ -f "/root/.bash_history" ]; then | |
| FOUND=1 | |
| if [ -h "/root/.bash_history" ]; then | |
| FOUNDFILES="${FOUNDFILES} bash:/root/.bash_history" | |
| fi | |
| fi | |
| if [ -f "/root/.sh_history" ]; then | |
| FOUND=1 | |
| if [ -h "/root/.sh_history" ]; then | |
| FOUNDFILES="${FOUNDFILES} Korn:/root/.sh_history" | |
| fi | |
| fi | |
| if [ -f "/root/.history" ]; then | |
| FOUND=1 | |
| if [ -h "/root/.history" ]; then | |
| FOUNDFILES="${FOUNDFILES} C-shell:/root/.history" | |
| fi | |
| fi | |
| if [ -f "/root/.zhistory" ]; then | |
| FOUND=1 | |
| if [ -h "/root/.zhistory" ]; then | |
| FOUNDFILES="${FOUNDFILES} zsh:/root/.zhistory" | |
| fi | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${FOUNDFILES}" ]; then | |
| test $FOUND -eq 1 && RKHTMPVAR="OK" || RKHTMPVAR="NONE_FOUND" | |
| display --to SCREEN+LOG --type PLAIN --color GREEN --result ${RKHTMPVAR} --log-indent 2 --screen-indent 4 HISTORY_CHECK | |
| else | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 HISTORY_CHECK | |
| for RKHTMPVAR in ${FOUNDFILES}; do | |
| SHELLNAME=`echo "${RKHTMPVAR}" | cut -d: -f1` | |
| FILENAME=`echo "${RKHTMPVAR}" | cut -d: -f2` | |
| display --to LOG --type WARNING HISTORY_CHECK_FOUND "`name2text \"${SHELLNAME}\"`" "`name2text \"${FILENAME}\"`" | |
| done | |
| fi | |
| return | |
| } | |
| do_system_config_files_check() { | |
| # | |
| # This function carries out checks on some of the system | |
| # software configurations. At present this checks the SSH | |
| # and system logging configurations. | |
| # | |
| if `check_test system_configs`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST system_configs | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 SYSTEM_CONFIGS_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST system_configs | |
| fi | |
| return | |
| fi | |
| if `check_test system_configs_ssh`; then | |
| display --to LOG --type INFO --nl STARTING_TEST system_configs_ssh | |
| # | |
| # First find out where the SSH configuration file is located. | |
| # | |
| SSH_CONFIG_FILE="" | |
| if [ -n "${SSH_CONFIG_DIR}" ]; then | |
| RKHTMPVAR="${SSH_CONFIG_DIR}" | |
| else | |
| RKHTMPVAR="/etc /etc/ssh /usr/local/etc /usr/local/etc/ssh" | |
| fi | |
| for DIR in ${RKHTMPVAR}; do | |
| if [ -f "${DIR}/sshd_config" ]; then | |
| SSH_CONFIG_FILE="${DIR}/sshd_config" | |
| break | |
| fi | |
| done | |
| if [ -n "${SSH_CONFIG_FILE}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE_SSH | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SYSTEM_CONFIGS_FILE_FOUND 'an' 'SSH' "${SSH_CONFIG_FILE}" | |
| display --to LOG --type INFO CONFIG_SSH_ROOT "${ALLOW_SSH_ROOT_USER}" | |
| display --to LOG --type INFO CONFIG_SSH_PROTV1 $ALLOW_SSH_PROT_V1 | |
| fi | |
| # | |
| # Now we check some of the configuration options. | |
| # | |
| # First we check for allowed root access. | |
| # | |
| RKHTMPVAR=`grep -i '^[ ]*PermitRootLogin[ =]' "${SSH_CONFIG_FILE}" 2>/dev/null | tail ${TAIL_OPT}1` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| # | |
| # Get the value that has been set. | |
| # | |
| RKHTMPVAR2=`echo ${RKHTMPVAR} | sed -e 's/^[^ =]*[ ]*=*[ ]*\([^ #]*\).*$/\1/' | tr '[:upper:]' '[:lower:]'` | |
| if [ "${RKHTMPVAR2}" = "${ALLOW_SSH_ROOT_USER}" ]; then | |
| test "${RKHTMPVAR2}" = "no" && RKHTMPVAR="NOT_ALLOWED" || RKHTMPVAR="ALLOWED" | |
| display --to SCREEN+LOG --type PLAIN --result ${RKHTMPVAR} --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_ROOT_FOUND | |
| display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_ROOT_FOUND1 "${RKHTMPVAR2}" | |
| display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_ROOT_FOUND2 "${ALLOW_SSH_ROOT_USER}" | |
| fi | |
| elif [ "${ALLOW_SSH_ROOT_USER}" = "unset" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result UNSET --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_ROOT_NOTFOUND | |
| fi | |
| # | |
| # Next we check to see if protocol version 1 is allowed. | |
| # | |
| RKHTMPVAR=`grep -i '^[ ]*Protocol[ =]' "${SSH_CONFIG_FILE}" 2>/dev/null | tail ${TAIL_OPT}1` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| # | |
| # See if the set protocol versions includes '1'. | |
| # | |
| RKHTMPVAR2=`echo ${RKHTMPVAR} | sed -e 's/^[^ =]*[ ]*=*[ ]*\([^ #]*\).*$/\1/'` | |
| RKHTMPVAR3=`echo "${RKHTMPVAR2}" | grep '1'` | |
| if [ -z "${RKHTMPVAR3}" -a $ALLOW_SSH_PROT_V1 -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO | |
| elif [ -n "${RKHTMPVAR3}" -a \( $ALLOW_SSH_PROT_V1 -eq 1 -o $ALLOW_SSH_PROT_V1 -eq 2 \) ]; then | |
| display --to SCREEN+LOG --type PLAIN --result ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_ROOT_FOUND | |
| display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_PROTO_DIFF1 "${RKHTMPVAR2}" | |
| display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_PROTO_DIFF2 "${ALLOW_SSH_PROT_V1}" | |
| fi | |
| elif [ $ALLOW_SSH_PROT_V1 -eq 2 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result UNSET --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_PROTO_NOTFOUND | |
| fi | |
| # | |
| # Finally we check for any other known suspicious configuration settings. | |
| # | |
| FOUND=0 | |
| FOUNDNAMES="" | |
| # | |
| # First check for the Ebury backdoor. | |
| # | |
| RKHTMPVAR=`grep -i '^[ ]*AuthorizedKeysFile[ =]' "${SSH_CONFIG_FILE}" 2>/dev/null | tail ${TAIL_OPT}1` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR2=`echo ${RKHTMPVAR} | sed -e 's/^[^ =]*[ ]*=*[ ]*\([^ #]*\).*$/\1/'` | |
| if [ "${RKHTMPVAR2}" = "/proc/self/environ" ]; then | |
| FOUND=1 | |
| FOUNDNAMES="${FOUNDNAMES} ebury" | |
| fi | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| if [ $FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_EXTRA | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_EXTRA | |
| for RKHTMPVAR in ${FOUNDNAMES}; do | |
| case "${RKHTMPVAR}" in | |
| ebury) | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_EBURY | |
| ;; | |
| esac | |
| done | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE_SSH | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST system_configs_ssh | |
| fi | |
| if `check_test system_configs_syslog`; then | |
| display --to LOG --type INFO --nl STARTING_TEST system_configs_syslog | |
| # | |
| # Next we find out if a system logging daemon is running. | |
| # | |
| TITLE_SHOWN=0 | |
| SYSLOG_SEEN=0; SYSTEMD_SEEN=0 | |
| METALOG_SEEN=0; SOCKLOG_SEEN=0 | |
| if [ -n "${PS_CMD}" ]; then | |
| PS_ARGS="ax" | |
| test $SUNOS -eq 1 -o $IRIXOS -eq 1 && PS_ARGS="-ef" | |
| RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E '(syslogd|syslog-ng)( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SYSLOG_SEEN=1 | |
| test $TITLE_SHOWN -eq 0 && display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ -n "`echo \"${RKHTMPVAR}\" | grep 'rsyslog'`" ]; then | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'rsyslog' | |
| elif [ -n "`echo \"${RKHTMPVAR}\" | grep 'syslog-ng'`" ]; then | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'syslog-ng' | |
| else | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'syslog' | |
| fi | |
| fi | |
| TITLE_SHOWN=1 | |
| fi | |
| RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'systemd-journald( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SYSTEMD_SEEN=1 | |
| if [ $TITLE_SHOWN -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'systemd-journald' | |
| fi | |
| TITLE_SHOWN=1 | |
| fi | |
| RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'metalog( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| METALOG_SEEN=1 | |
| if [ $TITLE_SHOWN -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'metalog' | |
| fi | |
| TITLE_SHOWN=1 | |
| fi | |
| RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | grep -E 'socklog( |$)' | grep -v 'grep'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| SOCKLOG_SEEN=1 | |
| if [ $TITLE_SHOWN -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_DAEMON 'socklog' | |
| fi | |
| TITLE_SHOWN=1 | |
| fi | |
| if [ $TITLE_SHOWN -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NOT_RUNNING | |
| fi | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' ps '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'ps' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'ps' | |
| fi | |
| fi | |
| # | |
| # Now loop through the system logging configuration files. | |
| # | |
| if [ -z "${SYSLOG_CONFIG_FILE}" ]; then | |
| SYSLOG_CONFIG_FILE="/etc/syslog.conf /etc/rsyslog.conf /etc/syslog-ng/syslog-ng.conf /etc/systemd/journald.conf /etc/systemd/systemd-journald.conf" | |
| fi | |
| if [ "${SYSLOG_CONFIG_FILE}" = "NONE" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WHITELISTED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| else | |
| FILEFOUND="" | |
| REM_LOGGING_FOUND=0 | |
| if [ $ALLOW_SYSLOG_REMOTE_LOGGING -eq 1 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SYSTEM_CONFIGS_SYSLOG_REMOTE_ALLOWED | |
| fi | |
| for FNAME in ${SYSLOG_CONFIG_FILE}; do | |
| test ! -f "${FNAME}" && continue | |
| # First, log where the configuration file is located. | |
| RKHTMPVAR="a" | |
| if [ -n "`echo \"${FNAME}\" | grep '/rsyslog\.conf$'`" ]; then | |
| FTYPE="rsyslog" | |
| RKHTMPVAR="an" | |
| elif [ -n "`echo \"${FNAME}\" | grep '/syslog-ng\.conf$'`" ]; then | |
| FTYPE="syslog-ng" | |
| elif [ -n "`echo \"${FNAME}\" | grep -E '/(systemd-)?journald\.conf$'`" ]; then | |
| FTYPE="systemd" | |
| else | |
| FTYPE="syslog" | |
| fi | |
| FILEFOUND="${FILEFOUND} ${FTYPE} " | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SYSTEM_CONFIGS_FILE_FOUND "${RKHTMPVAR}" "${FTYPE}" "`name2text \"${FNAME}\"`" | |
| fi | |
| # Next see if the configuration file allows remote logging. | |
| if [ "${FTYPE}" != "systemd" ]; then | |
| RKHTMPVAR="" | |
| if [ -n "`echo \"${FNAME}\" | grep -E '/r?syslog\.conf$'`" ]; then | |
| RKHTMPVAR=`grep -E -i '^[^#].*[ ](@|:omrelp:).' "${FNAME}" | grep -E -i -v '(@|:omrelp:)127\.'` | |
| else | |
| # | |
| # For syslog-ng we must look for a destination | |
| # block which uses TCP or UDP. | |
| # | |
| RKHTMPVAR=`${AWK_CMD} '/^[ ]*destination( | |$)/, /}/ { print $0 }' "${FNAME}" | grep -E -i '( | |\{|^)(tcp|udp)6?( | |\(|$)' | grep -E -v -i '(tcp|udp)6?[ ]*\([ ]*("[ ]*)?127\.'` | |
| fi | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| REM_LOGGING_FOUND=1 | |
| display --to LOG --type INFO SYSTEM_CONFIGS_SYSLOG_REMOTE_LOG "${FTYPE}" "${RKHTMPVAR}" | |
| fi | |
| fi | |
| done | |
| # | |
| # Now display the results. We need to rank these so | |
| # that the warnings are shown before anything else. | |
| # | |
| if [ $SYSLOG_SEEN -eq 1 -a -z "`echo \"${FILEFOUND}\" | grep -E ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NO_FILE 'syslog' | |
| elif [ $SYSTEMD_SEEN -eq 1 -a -z "`echo \"${FILEFOUND}\" | grep ' systemd '`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NO_FILE 'systemd-journald' | |
| elif [ -n "${FILEFOUND}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE | |
| fi | |
| # | |
| # We only display the remote logging result if a configuration file was found. | |
| # | |
| if [ -n "`echo \"${FILEFOUND}\" | grep -E ' (syslog|rsyslog|syslog-ng) '`" ]; then | |
| if [ $ALLOW_SYSLOG_REMOTE_LOGGING -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE | |
| elif [ $REM_LOGGING_FOUND -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NOT_ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE | |
| fi | |
| fi | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST system_configs_syslog | |
| fi | |
| return | |
| } | |
| do_dev_whitelist_check() { | |
| # | |
| # The check of /dev files has two methods. One uses a simple | |
| # top-level file check, the other is more thorough and does a | |
| # complete 'find' on the /dev directory. However, the check on | |
| # whether the given file is whitelisted is the same for both | |
| # methods. As such, it makes sense to use a function rather than | |
| # repeating the code for each method. | |
| # | |
| FTYPE=`${FILE_CMD} "${RKHTMPVAR}" 2>&1 | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| if [ $MACOSX -eq 1 -a -n "`echo \"${FTYPE}\" | grep 'universal binary'`" ]; then | |
| FTYPE=`echo "${FTYPE}" | tail ${TAIL_OPT}1` | |
| fi | |
| if [ -z "`echo \"${FTYPE}\" | grep -E -v '(character special|block special|socket|fifo \(named pipe\)|symbolic link to|empty|directory|/MAKEDEV:)'`" ]; then | |
| return | |
| fi | |
| # | |
| # Not sure why but '?' doesn't seem to need to be escaped. Neither do parentheses or braces. | |
| # Also, cannot get the '[]' characters to work in the bracket expression. So these are handled individually. | |
| # | |
| FNAMEGREP=`echo "${RKHTMPVAR}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${ALLOWDEVFILES}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILESYSTEM_DEV_FILE_WL "`name2text \"${RKHTMPVAR}\"`" | |
| fi | |
| else | |
| FOUNDFILES="${FOUNDFILES} | |
| ${RKHTMPVAR}: ${FTYPE}" | |
| fi | |
| return | |
| } | |
| do_filesystem_check() { | |
| # | |
| # This function carries out various checks on the local filesystem. | |
| # | |
| if `check_test filesystem`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST filesystem | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 2 FILESYSTEM_START | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST filesystem | |
| fi | |
| return | |
| fi | |
| if [ ! -d "/dev" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK | |
| display --to LOG --type WARNING FILESYSTEM_DEV_CHECK_NO_DEV | |
| elif [ -z "${FILE_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' file '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'file' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'file' | |
| fi | |
| elif [ "${SCAN_MODE_DEV}" = "THOROUGH" -a -z "${FIND_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' find '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'find' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'find' | |
| fi | |
| else | |
| # | |
| # Now we can run the check on /dev. | |
| # | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO CONFIG_SCAN_MODE_DEV "${SCAN_MODE_DEV}" | |
| fi | |
| # | |
| # First we expand the whitelist option to ensure | |
| # that any wildcard entries are the most recent. | |
| # | |
| if [ -n "${ALLOWDEVFILE_OPT}" ]; then | |
| ALLOWDEVFILES=`expand_paths ALLOWDEVFILE_OPT` | |
| fi | |
| # | |
| # Note: We do not look for hidden files here - that is, | |
| # those beginning with a dot. Any hidden files will be | |
| # picked up in the next check. | |
| # Note2: Filenames can contain a colon (:), so we need to | |
| # be careful in separating the filename from the file type. | |
| # Note3: We have to cater for *BSD systems which may have | |
| # fdesc/fdescfs mounted. If it is, then we must skip over | |
| # any detected file descriptors. | |
| # | |
| FDESCFS=0 | |
| FOUNDFILES="" | |
| if [ $BSDOS -eq 1 ]; then | |
| RKHTMPVAR=`find_cmd mount` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| test -n "`${RKHTMPVAR} 2>/dev/null | grep -E '^fdesc(fs)? .*(type fdesc|\(fdescfs\))'`" && FDESCFS=1 | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'mount' | |
| fi | |
| fi | |
| if [ "${SCAN_MODE_DEV}" = "LAZY" ]; then | |
| for RKHTMPVAR in /dev/*; do | |
| test -d "${RKHTMPVAR}" -o -h "${RKHTMPVAR}" && continue | |
| if [ $FDESCFS -eq 1 ]; then | |
| test -n "`echo \"${RKHTMPVAR}/\" | grep '^/dev/fd/[0-9][0-9]*'`" && continue | |
| fi | |
| do_dev_whitelist_check | |
| done | |
| else | |
| IFS=$IFSNL | |
| for RKHTMPVAR in `${FIND_CMD} /dev ! -type d -a ! -type l 2>/dev/null`; do | |
| if [ $FDESCFS -eq 1 ]; then | |
| test -n "`echo \"${RKHTMPVAR}/\" | grep '^/dev/fd/[0-9][0-9]*'`" && continue | |
| fi | |
| test -z "`echo \"${RKHTMPVAR}\" | grep '/\.[^/]*$'`" && do_dev_whitelist_check | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Now display the results. | |
| # | |
| FOUNDFILES=`echo "${FOUNDFILES}" | sed -e '/^$/d'` | |
| if [ -z "${FOUNDFILES}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK | |
| display --to LOG --type WARNING FILESYSTEM_DEV_FILE_FOUND '/dev' | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${FOUNDFILES}; do | |
| FTYPE=`echo "${RKHTMPVAR}" | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| FNAME=`echo "${RKHTMPVAR}" | sed -e 's/: [^:]*$//'` | |
| display --to LOG --type PLAIN --log-indent 9 NAME "`name2text \"${FNAME}\"`: ${FTYPE}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| # | |
| # Now we check various directories for hidden files and | |
| # directories. We must have the 'file' command for this | |
| # test to run. | |
| # | |
| # First we look in two sets of directories. One set we search | |
| # recursively, using 'find', the other set we only search to | |
| # one-level. If we have no 'find' command, then all the | |
| # directories are only searched to one-level. | |
| # | |
| if [ -z "${FILE_CMD}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK | |
| if [ -n "`echo \"${DISABLED_CMDS}\" | grep ' file '`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD 'file' | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'file' | |
| fi | |
| return | |
| fi | |
| FOUNDDIRS="" | |
| FOUNDFILES="" | |
| LOOKINDIRS="" | |
| SHORTSEARCHDIRS="/usr /etc" | |
| LONGSEARCHDIRS="/dev /bin /usr/man /usr/share/man /usr/bin /usr/sbin /sbin" | |
| if [ -z "${FIND_CMD}" ]; then | |
| SHORTSEARCHDIRS="${SHORTSEARCHDIRS} ${LONGSEARCHDIRS}" | |
| LONGSEARCHDIRS="" | |
| fi | |
| for DIR in ${SHORTSEARCHDIRS}; do | |
| if [ -d "${DIR}" ]; then | |
| RKHTMPVAR=`ls -1d ${DIR}/.* 2>/dev/null | grep -E -v '/\.\.?$'` | |
| test -n "${RKHTMPVAR}" && LOOKINDIRS="${LOOKINDIRS} | |
| ${RKHTMPVAR}" | |
| fi | |
| done | |
| for DIR in ${LONGSEARCHDIRS}; do | |
| if [ -d "${DIR}" ]; then | |
| RKHTMPVAR=`${FIND_CMD} "${DIR}" -name ".*" 2>/dev/null` | |
| test -n "${RKHTMPVAR}" && LOOKINDIRS="${LOOKINDIRS} | |
| ${RKHTMPVAR}" | |
| fi | |
| done | |
| # | |
| # We expand the whitelisting options to ensure that any | |
| # wildcard entries are the most recent. | |
| # | |
| if [ -n "${ALLOWHIDDENFILE_OPT}" ]; then | |
| ALLOWHIDDENFILES=`expand_paths ALLOWHIDDENFILE_OPT` | |
| fi | |
| if [ -n "${ALLOWHIDDENDIR_OPT}" ]; then | |
| ALLOWHIDDENDIRS=`expand_paths ALLOWHIDDENDIR_OPT` | |
| fi | |
| # | |
| # Next we look for any whitelisted files and directories. We also | |
| # exclude certain types of files. | |
| # | |
| IFS=$IFSNL | |
| for FNAME in ${LOOKINDIRS}; do | |
| if [ $FDESCFS -eq 1 ]; then | |
| test -n "`echo \"${FNAME}/\" | grep '^/dev/fd/[0-9][0-9]*'`" && continue | |
| fi | |
| FTYPE=`${FILE_CMD} "${FNAME}" 2>&1 | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| test -n "`echo \"${FTYPE}\" | grep -E 'character special|block special|empty'`" && continue | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ -n "`echo \"${FTYPE}\" | grep 'directory'`" ]; then | |
| if [ -n "`echo \"${ALLOWHIDDENDIRS}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILESYSTEM_HIDDEN_DIR_WL "`name2text \"${FNAME}\"`" | |
| fi | |
| else | |
| FOUNDDIRS="${FOUNDDIRS} | |
| ${FNAME}: ${FTYPE}" | |
| fi | |
| else | |
| if [ -n "`echo \"${ALLOWHIDDENFILES}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILESYSTEM_HIDDEN_FILE_WL "`name2text \"${FNAME}\"`" | |
| fi | |
| else | |
| FOUNDFILES="${FOUNDFILES} | |
| ${FNAME}: ${FTYPE}" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| FOUNDDIRS=`echo "${FOUNDDIRS}" | sed -e '/^$/d'` | |
| FOUNDFILES=`echo "${FOUNDFILES}" | sed -e '/^$/d'` | |
| # | |
| # Now display the results. | |
| # | |
| if [ -z "${FOUNDDIRS}" -a -z "${FOUNDFILES}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${FOUNDDIRS}; do | |
| FTYPE=`echo "${RKHTMPVAR}" | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| FNAME=`echo "${RKHTMPVAR}" | sed -e 's/: [^:]*$//'` | |
| if [ "${FTYPE}" = "directory" ]; then | |
| display --to LOG --type WARNING FILESYSTEM_HIDDEN_DIR_FOUND "`name2text \"${FNAME}\"`" | |
| else | |
| display --to LOG --type WARNING FILESYSTEM_HIDDEN_DIR_FOUND "`name2text \"${FNAME}\"`: ${FTYPE}" | |
| fi | |
| done | |
| for RKHTMPVAR in ${FOUNDFILES}; do | |
| FTYPE=`echo "${RKHTMPVAR}" | ${AWK_CMD} -F':' '{ print $NF }' | cut -c2-` | |
| FNAME=`echo "${RKHTMPVAR}" | sed -e 's/: [^:]*$//'` | |
| display --to LOG --type WARNING FILESYSTEM_HIDDEN_FILE_FOUND "`name2text \"${FNAME}\"`: ${FTYPE}" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| # | |
| # Next check if any configured log files are missing. | |
| # | |
| FOUNDFILES="" | |
| if [ -n "${LOGFILE_MISSING}" ]; then | |
| MISSINGFILES="" | |
| for FNAME in ${LOGFILE_MISSING}; do | |
| if [ ! -f "${FNAME}" ]; then | |
| MISSINGFILES="${MISSINGFILES} | |
| ${FNAME}" | |
| fi | |
| done | |
| # | |
| # Now show the results. | |
| # | |
| MISSINGFILES=`echo "${MISSINGFILES}" | sed -e '/^$/d'` | |
| if [ -z "${MISSINGFILES}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_MISSING --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_LOGFILE_MISSING | |
| else | |
| FOUNDFILES="${MISSINGFILES}" | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_LOGFILE_MISSING | |
| IFS=$IFSNL | |
| for FNAME in ${MISSINGFILES}; do | |
| display --to LOG --type WARNING FILESYSTEM_LOGFILE_MISSING_FOUND "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 FILESYSTEM_LOGFILE_MISSING | |
| display --to LOG --type INFO FILESYSTEM_LOGFILE_MISS_DISABLED | |
| fi | |
| # | |
| # Next check if any configured log files are empty or missing. | |
| # | |
| if [ -n "${LOGFILE_EMPTY}" ]; then | |
| EMPTYFILES="" | |
| MISSINGFILES="" | |
| for FNAME in ${LOGFILE_EMPTY}; do | |
| if [ ! -f "${FNAME}" ]; then | |
| # | |
| # Only record a missing log file if the previous | |
| # missing log file test didn't check it. | |
| # | |
| if [ -z "`echo \"${FOUNDFILES}\" | grep \"^${FNAME}$\"`" ]; then | |
| MISSINGFILES="${MISSINGFILES} | |
| ${FNAME}" | |
| fi | |
| elif [ ! -s "${FNAME}" ]; then | |
| EMPTYFILES="${EMPTYFILES} | |
| ${FNAME}" | |
| fi | |
| done | |
| # | |
| # Now show the results. | |
| # | |
| EMPTYFILES=`echo "${EMPTYFILES}" | sed -e '/^$/d'` | |
| MISSINGFILES=`echo "${MISSINGFILES}" | sed -e '/^$/d'` | |
| if [ -z "${EMPTYFILES}" -a -z "${MISSINGFILES}" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_LOGFILE_EMPTY | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_LOGFILE_EMPTY | |
| IFS=$IFSNL | |
| for FNAME in ${EMPTYFILES}; do | |
| display --to LOG --type WARNING FILESYSTEM_LOGFILE_EMPTY_FOUND "`name2text \"${FNAME}\"`" | |
| done | |
| for FNAME in ${MISSINGFILES}; do | |
| display --to LOG --type WARNING FILESYSTEM_LOGFILE_MISSING_FOUND "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type PLAIN --result SKIPPED --log-indent 2 FILESYSTEM_LOGFILE_EMPTY | |
| display --to LOG --type INFO FILESYSTEM_LOGFILE_EMPTY_DISABLED | |
| fi | |
| return | |
| } | |
| do_local_host_checks() { | |
| # | |
| # This function carries out a sequence of tests on the local | |
| # host. | |
| # | |
| if `check_test local_host`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST local_host | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW CHECK_LOCALHOST | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST local_host | |
| fi | |
| return | |
| fi | |
| # | |
| # We start by performing checks on the startup files. | |
| # | |
| do_system_startup_file_checks | |
| # | |
| # Now we check the /etc/passwd file, and run some checks | |
| # on the accounts and groups. | |
| # | |
| do_group_accounts_check | |
| # | |
| # Next check some of the system configuration files. | |
| # | |
| do_system_config_files_check | |
| # | |
| # Finally check the filesystem for hidden files, directories etc. | |
| # | |
| do_filesystem_check | |
| keypresspause | |
| return | |
| } | |
| do_app_checks() { | |
| # | |
| # This function carries out a sequence of application checks. | |
| # | |
| if `check_test apps`; then | |
| display --to LOG --type INFO --screen-nl --nl STARTING_TEST apps | |
| else | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO --nl USER_DISABLED_TEST apps | |
| fi | |
| return | |
| fi | |
| # | |
| # First we check that our apps data file is usable. | |
| # | |
| if [ ! -e "${DB_PATH}/programs_bad.dat" -o ! -s "${DB_PATH}/programs_bad.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING CHECK_APPS | |
| display --to LOG --type WARNING APPS_DAT_MISSING "${DB_PATH}/programs_bad.dat" | |
| return | |
| elif [ ! -f "${DB_PATH}/programs_bad.dat" -o -h "${DB_PATH}/programs_bad.dat" ]; then | |
| display --to SCREEN+LOG --type PLAIN --color RED --result WARNING CHECK_APPS | |
| display --to LOG --type WARNING APPS_DAT_NOTAFILE "${DB_PATH}/programs_bad.dat" | |
| return | |
| fi | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --nl-after CHECK_APPS | |
| # | |
| # We loop through the applications and obtain the version number. | |
| # This is then checked against the file of known bad versions. | |
| # We build up a list of application names, the version number, | |
| # and whether it is known to be bad or not. When this has all | |
| # been done, we then display the results. | |
| # | |
| # The results line for each application is made up of percent (%) | |
| # delimited fields. They are: | |
| # | |
| # application%description%version%if known bad%whole version number | |
| # | |
| # A 'version' number of '-1' means the application was not found. | |
| # | |
| # An 'if known bad' number of: | |
| # | |
| # '-1' means a specific version of the application is whitelisted, | |
| # '-2' means the application is whitelisted, regardless of version. | |
| # | |
| APPS_COUNT=0 | |
| APP_RESULTS="" | |
| APP_NAMES="exim:Exim MTA | |
| gpg:GnuPG | |
| httpd:Apache | |
| named:Bind DNS | |
| openssl:OpenSSL | |
| php:PHP | |
| procmail:Procmail MTA | |
| proftpd:ProFTPD | |
| sshd:OpenSSH" | |
| APPS_TOTAL_COUNT=`echo "${APP_NAMES}" | wc -l | tr -d ' '` | |
| IFS=$IFSNL | |
| for APP in ${APP_NAMES}; do | |
| APP=`echo ${APP} | sed -e 's/^[ ]*//'` | |
| APPLICATION=`echo ${APP} | cut -d: -f1` | |
| APPLICATION_DESC=`echo ${APP} | cut -d: -f2-` | |
| IFS=$RKHIFS | |
| APP_CMD_FOUND=`find_cmd ${APPLICATION}` | |
| IFS=$IFSNL | |
| if [ -z "${APP_CMD_FOUND}" ]; then | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%-1" | |
| continue | |
| fi | |
| # | |
| # Find out the version of the application. | |
| # | |
| APPS_COUNT=`expr ${APPS_COUNT} + 1` | |
| VERSION="" | |
| WHOLE_VERSION="" | |
| # | |
| # Applications which are whitelisted completely (no specific | |
| # version number), are handled first. | |
| # | |
| if [ -n "`echo \"${APP_WHITELIST}\" | grep \" ${APPLICATION} \"`" ]; then | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%0%-2" | |
| else | |
| case "${APPLICATION}" in | |
| exim) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -bV 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep '^Exim version [0-9]' | ${AWK_CMD} '{ print $3 }'` | |
| ;; | |
| gpg) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} --version --homedir / 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep 'GnuPG' | ${AWK_CMD} '{ print $3 }'` | |
| ;; | |
| httpd) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep -i '^Server version:[ ][ ]*Apache/[0-9]' | cut -d' ' -f3 | cut -d'/' -f2` | |
| ;; | |
| named) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep -E '^(named|BIND)[ ][ ]*[0-9]' | grep -v '/' | ${AWK_CMD} '{ print $2 }'` | |
| if [ -n "`echo \"${VERSION}\" | grep '^[^-]*\.[0-9][0-9]*-P[^-]*-'`" ]; then | |
| VERSION=`echo "${VERSION}" | cut -d'-' -f1-2` | |
| elif [ -n "`echo \"${VERSION}\" | grep '^[^-]*\.[0-9][0-9]*-[^P]'`" ]; then | |
| VERSION=`echo "${VERSION}" | cut -d'-' -f1` | |
| fi | |
| if [ -z "${VERSION}" ]; then | |
| VERSION=`${APP_CMD_FOUND} -v | ${AWK_CMD} '{ print $2 }'` | |
| fi | |
| ;; | |
| openssl) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} version 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep '^OpenSSL[ ][ ]*[0-9]' | cut -d' ' -f2` | |
| if [ -n "`echo \"${VERSION}\" | grep '^[^-]*-fips'`" ]; then | |
| VERSION=`echo "${VERSION}" | cut -d'-' -f1` | |
| fi | |
| ;; | |
| php) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep '^PHP[ ][ ]*[0-9]' | ${AWK_CMD} '{ print $2 }' | cut -d'-' -f1` | |
| ;; | |
| procmail) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>&1` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep '^procmail[ ][ ]*v[0-9]' | ${AWK_CMD} '{ print $2 }' | sed -e 's/^v//'` | |
| ;; | |
| proftpd) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>&1` | |
| VERSION=`echo "${WHOLE_VERSION}" | sed -e 's/^.*\(ProFTPD.*\)$/\1/' | grep '^ProFTPD[ ][ ]*Version[ ][ ]*[0-9]' | ${AWK_CMD} '{ print $3 }'` | |
| ;; | |
| sshd) | |
| WHOLE_VERSION=`${APP_CMD_FOUND} -t -d 2>&1` | |
| VERSION=`echo "${WHOLE_VERSION}" | grep 'sshd version OpenSSH' | sed -e 's/^.*sshd version OpenSSH_//' | cut -d' ' -f1` | |
| if [ -n "`echo \"${VERSION}\" | grep '+'`" ]; then | |
| VERSION=`echo "${VERSION}" | cut -d'+' -f1` | |
| fi | |
| ;; | |
| esac | |
| VERSION=`echo "${VERSION}" | tr -d '\r'` | |
| WHOLE_VERSION=`echo "${WHOLE_VERSION}" | tr -d '\r'` | |
| if [ -z "${VERSION}" ]; then | |
| WHOLE_VERSION=`echo "${WHOLE_VERSION}" | tr '\n' '%'` | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%%0%${WHOLE_VERSION}" | |
| continue | |
| fi | |
| # | |
| # Now see if the application version is known to be bad. | |
| # | |
| RKHTMPVAR=`echo "${VERSION}" | sed -e 's/\./\\\./g'` | |
| if [ -n "`echo \"${APP_WHITELIST}\" | grep -i \" ${APPLICATION}:${RKHTMPVAR} \"`" ]; then | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%${VERSION}%-1" | |
| elif [ -n "`grep -E -i \"^${APPLICATION}:.* ${RKHTMPVAR}( |$)\" \"${DB_PATH}/programs_bad.dat\" 2>&1`" ]; then | |
| APPS_FAILED_COUNT=`expr ${APPS_FAILED_COUNT} + 1` | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%${VERSION}%1" | |
| else | |
| APP_RESULTS="${APP_RESULTS} | |
| ${APPLICATION}%${APPLICATION_DESC}%${VERSION}%0" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Now display the results. | |
| # | |
| if [ $APPS_COUNT -eq 0 ]; then | |
| display --to SCREEN+LOG --type PLAIN --color YELLOW --nl --result SKIPPED CHECK_APPS | |
| display --to LOG --type INFO APPS_NONE_FOUND | |
| else | |
| IFS=$IFSNL | |
| for RKHTMPVAR in ${APP_RESULTS}; do | |
| APPLICATION=`echo "${RKHTMPVAR}" | cut -d% -f1` | |
| APPLICATION_DESC=`echo "${RKHTMPVAR}" | cut -d% -f2` | |
| VERSION=`echo "${RKHTMPVAR}" | cut -d% -f3` | |
| if [ -z "${VERSION}" ]; then | |
| WHOLE_VERSION=`echo "${RKHTMPVAR}" | cut -d% -f5- | tr '%' '\n'` | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| if [ -n "${WHOLE_VERSION}" ]; then | |
| display --to LOG --type INFO APPS_CHECK_WHOLE_VERSION_USED "${APPLICATION}" "${WHOLE_VERSION}" | |
| else | |
| display --to LOG --type INFO APPS_CHECK_VERSION_UNKNOWN "${APPLICATION}" | |
| fi | |
| elif [ "${VERSION}" = "-1" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO APPS_NOT_FOUND "${APPLICATION}" | |
| fi | |
| else | |
| ISBAD=`echo "${RKHTMPVAR}" | cut -d% -f4` | |
| if [ -n "`echo $ECHOOPT \"${ISBAD}\" | grep '[^-0-9]'`" ]; then | |
| display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| display --to LOG --type INFO APPS_CHECK_VERSION_UNKNOWN "${APPLICATION}" | |
| elif [ $ISBAD -eq -2 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO APPS_CHECK_WL "${APPLICATION}" | |
| fi | |
| elif [ $ISBAD -eq -1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO APPS_CHECK_VERSION_WL "${APPLICATION}" "${VERSION}" | |
| fi | |
| elif [ $ISBAD -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| display --to LOG --type WARNING APPS_CHECK_FOUND "${APPLICATION}" "${VERSION}" | |
| else | |
| display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO APPS_CHECK_VERSION_FOUND "${APPLICATION}" "${VERSION}" | |
| fi | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| display --to LOG --type INFO APPS_TOTAL_COUNT $APPS_COUNT $APPS_TOTAL_COUNT | |
| return | |
| } | |
| display_check_summary() { | |
| # | |
| # This function displays a short summary of some of the | |
| # groups of checks performed. | |
| # | |
| if [ $QUIET -eq 0 -o \( $SHOWWARNINGSONLY -eq 1 -a $WARNING_COUNT -gt 0 \) ]; then | |
| RKHTMPVAR=2 | |
| else | |
| RKHTMPVAR=1 | |
| fi | |
| display --to SCREEN+LOG --type PLAIN --nl ${RKHTMPVAR} SUMMARY_TITLE1 | |
| display --to SCREEN+LOG --type PLAIN SUMMARY_TITLE2 | |
| # | |
| # Do file properties summary. | |
| # | |
| display --to SCREEN+LOG --type PLAIN --nl SUMMARY_PROP_SCAN | |
| if `check_test properties`; then | |
| if [ $SUMMARY_PROP_REQCMDS -eq 1 ]; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_REQCMDS | |
| fi | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_COUNT $PROP_FILE_LIST_COUNT | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_FAILED $PROP_FAILED_COUNT | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED | |
| fi | |
| # | |
| # Do rootkit checks summary. | |
| # | |
| display --to SCREEN+LOG --type PLAIN --nl SUMMARY_RKT_SCAN | |
| if `check_test rootkits || check_test startup_files` || test $ROOTKIT_COUNT -gt 0; then | |
| RKHTMPVAR2="" | |
| if [ -n "${ROOTKIT_FAILED_NAMES}" ]; then | |
| ROOTKIT_FAILED_NAMES=`echo "${ROOTKIT_FAILED_NAMES}" | sed -e 's/, */,/g; s/,$//'` | |
| IFS="," | |
| for RTKT_NAME in ${ROOTKIT_FAILED_NAMES}; do | |
| if [ -z "`echo \" ${RKHTMPVAR2},\" | grep \" ${RTKT_NAME},\"`" ]; then | |
| RKHTMPVAR2="${RKHTMPVAR2}${RTKT_NAME}, " | |
| else | |
| ROOTKIT_FAILED_COUNT=`expr $ROOTKIT_FAILED_COUNT - 1` | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| RKHTMPVAR2=`echo "${RKHTMPVAR2}" | sed -e 's/, $//'` | |
| fi | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_COUNT $ROOTKIT_COUNT | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_FAILED $ROOTKIT_FAILED_COUNT | |
| test -n "${RKHTMPVAR2}" && display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_NAMES "${RKHTMPVAR2}" | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED | |
| fi | |
| # | |
| # Do application check summary. | |
| # | |
| display --to SCREEN+LOG --type PLAIN --nl SUMMARY_APPS_SCAN | |
| if `check_test apps`; then | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_APPS_COUNT $APPS_COUNT | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_APPS_FAILED $APPS_FAILED_COUNT | |
| else | |
| display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED | |
| fi | |
| # | |
| # Display the amount of time the system check took. | |
| # | |
| if [ $SHOW_SUMMARY_TIME -gt 0 ]; then | |
| if [ $SHOW_SUMMARY_TIME -eq 1 ]; then | |
| RKHTMPVAR="SCREEN" | |
| elif [ $SHOW_SUMMARY_TIME -eq 2 ]; then | |
| RKHTMPVAR="LOG" | |
| else | |
| RKHTMPVAR="SCREEN+LOG" | |
| fi | |
| if [ $BEGINTIME -eq 0 ]; then | |
| display --to ${RKHTMPVAR} --type PLAIN --nl SUMMARY_NO_SCAN_TIME | |
| else | |
| display --to ${RKHTMPVAR} --type PLAIN --nl SUMMARY_SCAN_TIME "${TOTAL_SCANTIME}" | |
| fi | |
| fi | |
| # | |
| # Display where the log file is located, if there is one. | |
| # | |
| if [ $NOLOG -eq 0 ]; then | |
| display --to SCREEN --type PLAIN --nl --nl-after SUMMARY_LOGFILE "${RKHLOGFILE}" | |
| else | |
| display --to SCREEN --type PLAIN --nl --nl-after SUMMARY_NO_LOGFILE | |
| fi | |
| return | |
| } | |
| do_system_check() { | |
| # | |
| # This function performs the various rootkit and security checks | |
| # for the program. We start by initialising variables used for | |
| # the rootkit checks. | |
| # | |
| display --to LOG --type PLAIN --nl CHECK_START | |
| do_system_check_initialisation | |
| # | |
| # Next, for Solaris we see if we are running Solaris 10 or not. | |
| # This can be useful to know in some of the tests since we will | |
| # use different mechanisms on Solaris 10 from those on Solaris | |
| # 9 and before. | |
| # | |
| SOL_PROC=0 | |
| SOLARISX="" | |
| if [ $SUNOS -eq 1 ]; then | |
| # | |
| # If we are running Solaris 10, then see if we have the | |
| # command pathname available. | |
| # | |
| # Solaris 10 and above should have the 'a.out' file | |
| # present. We use the PID of 1 here since it should exist | |
| # on all systems. | |
| # | |
| # If we are running Solaris 10 (or above), then we add | |
| # the '-X' option to the 'lsof' command in order to get | |
| # the deleted files. | |
| # | |
| if [ -h "/proc/1/path/a.out" ]; then | |
| SOLARISX='-X' | |
| test $HAVE_READLINK -eq 1 && SOL_PROC=1 | |
| fi | |
| fi | |
| # | |
| # Record the start time if we can. The total time taken for | |
| # scanning will only be calculated and displayed if the | |
| # start time can be set. | |
| # | |
| BEGINTIME=0 | |
| ENDTIME=0 | |
| if [ -n "$SECONDS" ]; then | |
| BEGINTIME=`echo $SECONDS | cut -d. -f1` | |
| elif [ $BSDOS -eq 1 -o $BUSYBOX -eq 1 ]; then | |
| BEGINTIME=`date +%s` | |
| elif [ -n "${PERL_CMD}" ]; then | |
| BEGINTIME=`${PERL_CMD} -e 'printf "%d\n", time;'` | |
| fi | |
| # | |
| # Send a start message to syslog if the user requested that. | |
| # | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| ${LOGGER_CMD} -t "${LOGGER_TAG}" -p ${USE_SYSLOG} "Rootkit hunter check started (version ${PROGRAM_version})" | |
| fi | |
| # | |
| # We start with checks of some of the commands (binaries) and | |
| # libraries on the system, to make sure that they have not | |
| # been tampered with. | |
| # | |
| do_system_commands_checks | |
| # | |
| # Next are the rootkit checks. | |
| # | |
| do_rootkit_checks | |
| # | |
| # Next are some network port, and interface checks. | |
| # | |
| do_network_checks | |
| # | |
| # Next are checks of the files for the local host. | |
| # | |
| do_local_host_checks | |
| # | |
| # Next are checks on specific applications. | |
| # | |
| do_app_checks | |
| # | |
| # Now record the end time. | |
| # | |
| if [ $BEGINTIME -ne 0 ]; then | |
| if [ -n "$SECONDS" ]; then | |
| ENDTIME=`echo $SECONDS | cut -d. -f1` | |
| elif [ $BSDOS -eq 1 -o $BUSYBOX -eq 1 ]; then | |
| ENDTIME=`date +%s` | |
| else | |
| ENDTIME=`${PERL_CMD} -e 'printf "%d\n", time;'` | |
| fi | |
| TOTAL_SCANTIME=`expr ${ENDTIME} - ${BEGINTIME}` | |
| TOTALMINS=`expr ${TOTAL_SCANTIME} / 60` | |
| TOTALSECS=`expr ${TOTAL_SCANTIME} % 60` | |
| if [ $TOTALMINS -gt 0 ]; then | |
| if [ $TOTALMINS -eq 1 ]; then | |
| TOTAL_SCANTIME="${TOTALMINS} minute and " | |
| else | |
| TOTAL_SCANTIME="${TOTALMINS} minutes and " | |
| fi | |
| else | |
| TOTAL_SCANTIME="" | |
| fi | |
| if [ $TOTALSECS -eq 1 ]; then | |
| TOTAL_SCANTIME="${TOTAL_SCANTIME}${TOTALSECS} second" | |
| else | |
| TOTAL_SCANTIME="${TOTAL_SCANTIME}${TOTALSECS} seconds" | |
| fi | |
| fi | |
| # | |
| # Display the summary of the results. | |
| # | |
| RKH_WARN_DISPLYD=0 | |
| if [ $SHOW_SUMMARY -eq 1 ]; then | |
| # | |
| # Unfortunately we need to do a kludge here! | |
| # The user may have used the '--quiet' option, | |
| # so we need to force the summary to be displayed. | |
| # By resetting the NOTTY variable we can get | |
| # the output shown. | |
| # | |
| OLD_NOTTY=$NOTTY | |
| test $SHOW_SUMMARY_OPT -eq 1 && NOTTY=0 | |
| display_check_summary | |
| if [ $SHOW_SUMMARY_WARNINGS_NUMBER -eq 0 ]; then | |
| if [ $WARNING_COUNT -eq 0 ]; then | |
| display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_NOT_FOUND | |
| else | |
| RKH_WARN_DISPLYD=1 | |
| display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND | |
| fi | |
| else | |
| if [ $WARNING_COUNT -eq 0 ]; then | |
| display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_NOT_FOUND0 | |
| else | |
| RKH_WARN_DISPLYD=1 | |
| if [ $WARNING_COUNT -eq 1 ]; then | |
| display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_NUMBER1 | |
| else | |
| display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_NUMBER "$WARNING_COUNT" | |
| fi | |
| fi | |
| fi | |
| if [ $WARNING_COUNT -gt 0 ]; then | |
| if [ $NOLOG -eq 1 ]; then | |
| display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_FOUND_RERUN | |
| else | |
| display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}" | |
| fi | |
| fi | |
| NOTTY=$OLD_NOTTY | |
| fi | |
| # | |
| # Send a finish message to syslog if the user requested that. | |
| # | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| ${LOGGER_CMD} -t "${LOGGER_TAG}" -p ${USE_SYSLOG} "Scanning took ${TOTAL_SCANTIME}" | |
| fi | |
| # | |
| # If some warning or error has been seen, then make sure the | |
| # user is told about it. We also set the return code, to allow | |
| # the user to detect it being non-zero. | |
| # | |
| if [ $WARNING_COUNT -gt 0 ]; then | |
| if [ $SHOWWARNINGSONLY -eq 1 -a $RKH_WARN_DISPLYD -eq 0 ]; then | |
| # | |
| # Unfortunately we need to do a kludge again! | |
| # By requesting that only warnings are shown, | |
| # the following output would not normally be | |
| # displayed (because they are not warnings). | |
| # | |
| OLD_NOTTY=$NOTTY | |
| NOTTY=0 | |
| if [ $SHOW_SUMMARY_WARNINGS_NUMBER -eq 0 ]; then | |
| display --to SCREEN --type PLAIN --nl CHECK_WARNINGS_FOUND | |
| else | |
| if [ $WARNING_COUNT -eq 1 ]; then | |
| display --to SCREEN --type PLAIN --nl CHECK_WARNINGS_FOUND_NUMBER1 | |
| else | |
| display --to SCREEN --type PLAIN --nl CHECK_WARNINGS_FOUND_NUMBER "$WARNING_COUNT" | |
| fi | |
| fi | |
| if [ $NOLOG -eq 1 ]; then | |
| display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_RERUN | |
| else | |
| display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}" | |
| fi | |
| NOTTY=$OLD_NOTTY | |
| fi | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| ${LOGGER_CMD} -t "${LOGGER_TAG}" -p ${USE_SYSLOG} "Please inspect this machine, because it may be infected." | |
| fi | |
| if [ -n "${MAILONWARNING}" ]; then | |
| eval "echo 'Please inspect this machine, because it may be infected.' | ${MAIL_CMD} ${MAILONWARNING}" | |
| fi | |
| RET_CODE=1 | |
| fi | |
| return | |
| } | |
| check_os_info() { | |
| # | |
| # This function checks the current O/S information against | |
| # that stored in the rkhunter.dat file. Any change could | |
| # mean that the file properties checks could give several | |
| # false-positive answers. As such we warn users that | |
| # a change has occurred. | |
| # | |
| OS_CHANGED=0 | |
| display --to LOG --type PLAIN --nl OSINFO_START | |
| # | |
| # First check if the host name has changed. | |
| # | |
| if [ $WARN_ON_OS_CHANGE -eq 1 ]; then | |
| IND_COUNT=9 | |
| OSINFO_WARNING="WARNING" | |
| else | |
| IND_COUNT=6 | |
| OSINFO_WARNING="INFO" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO FILE_PROP_NO_OS_WARNING | |
| fi | |
| fi | |
| OLD_HOST=`grep '^Host:' "${RKHDAT_FILE}" | cut -d: -f2-` | |
| if [ "${HOST_NAME}" != "${OLD_HOST}" ]; then | |
| OS_CHANGED=1 | |
| display --to LOG --type "${OSINFO_WARNING}" OSINFO_HOST_CHANGE1 | |
| display --to LOG --type PLAIN --log-indent $IND_COUNT OSINFO_HOST_CHANGE2 "${OLD_HOST}" "${HOST_NAME}" | |
| fi | |
| # | |
| # Next check if the O/S name has changed. | |
| # | |
| OLD_OSNAME=`grep '^OS:' "${RKHDAT_FILE}" | cut -d: -f2-` | |
| if [ "${OSNAME}" != "${OLD_OSNAME}" ]; then | |
| OS_CHANGED=1 | |
| display --to LOG --type "${OSINFO_WARNING}" OSINFO_OSVER_CHANGE1 | |
| display --to LOG --type PLAIN --log-indent $IND_COUNT OSINFO_OSVER_CHANGE2 "${OLD_OSNAME}" "${OSNAME}" | |
| fi | |
| # | |
| # Check if the prelinking status has changed. | |
| # | |
| if [ -z "`grep '^Prelinked:Yes' \"${RKHDAT_FILE}\"`" ]; then | |
| OLD_PRELINK=0 | |
| else | |
| OLD_PRELINK=1 | |
| fi | |
| if [ $PRELINKED -ne $OLD_PRELINK ]; then | |
| OS_CHANGED=1 | |
| if [ $PRELINKED -eq 1 ]; then | |
| display --to LOG --type "${OSINFO_WARNING}" OSINFO_PRELINK_CHANGE '' | |
| else | |
| display --to LOG --type "${OSINFO_WARNING}" OSINFO_PRELINK_CHANGE 'not ' | |
| fi | |
| fi | |
| # | |
| # Check if the system architecture has changed. We treat | |
| # the i386-type architectures as the same. We also treat | |
| # the sun-type archictures the same as 'sparc'. | |
| # | |
| OLD_ARCH=`grep '^Arch:' "${RKHDAT_FILE}" | cut -d: -f2-` | |
| if [ -n "`echo ${OLD_ARCH} | grep 'i[0-9]86'`" ]; then | |
| OLD_ARCH_TYPE="i386" | |
| elif [ -n "`echo ${OLD_ARCH} | grep 'sun[0-9][a-z]'`" -o -n "`echo ${OLD_ARCH} | grep 'sparc'`" ]; then | |
| OLD_ARCH_TYPE="sparc" | |
| else | |
| OLD_ARCH_TYPE=$OLD_ARCH | |
| fi | |
| if [ -n "`echo ${ARCH} | grep 'i[0-9]86'`" ]; then | |
| ARCH_TYPE="i386" | |
| elif [ -n "`echo ${ARCH} | grep 'sun[0-9][a-z]'`" -o -n "`echo ${ARCH} | grep 'sparc'`" ]; then | |
| ARCH_TYPE="sparc" | |
| else | |
| ARCH_TYPE=$ARCH | |
| fi | |
| if [ "${OLD_ARCH_TYPE}" != "${ARCH_TYPE}" ]; then | |
| OS_CHANGED=1 | |
| display --to LOG --type "${OSINFO_WARNING}" OSINFO_ARCH_CHANGE1 | |
| display --to LOG --type PLAIN --log-indent $IND_COUNT OSINFO_ARCH_CHANGE2 "${OLD_ARCH}" "${ARCH}" | |
| fi | |
| if [ $OS_CHANGED -eq 1 ]; then | |
| display --to LOG --type PLAIN --log-indent $IND_COUNT OSINFO_MSG1 | |
| if [ $UPDT_ON_OS_CHANGE -eq 0 ]; then | |
| display --to LOG --type PLAIN --log-indent $IND_COUNT OSINFO_MSG2 | |
| test $WARN_ON_OS_CHANGE -eq 1 && display --to LOG --type WARNING --nl PROPUPD_WARN | |
| else | |
| PROP_UPDATE=1 | |
| display --to LOG --type INFO OSINFO_DO_UPDT | |
| fi | |
| else | |
| display --to LOG --type INFO OSINFO_END | |
| fi | |
| return | |
| } | |
| set_file_prop_dirs_files() { | |
| # | |
| # This function sets up the list of directories we look in, | |
| # and the list of files we look for, in order to perform | |
| # the file properties checks. | |
| # | |
| # Any non-existent files are simply left in for the checks | |
| # to skip over. However, any symbolic links are expanded and | |
| # the result of the link is added to the list. This avoids | |
| # any attempt to simply replace a link, and avoid it being | |
| # detected by the file hash value check. | |
| # | |
| # We also check to see if any of the directories are links. | |
| # If it is then we add the link target directory. | |
| # | |
| PROP_DIR_LIST="" | |
| # | |
| # We have to change BINDIR to a newline-separated list here | |
| # because USER_DIR_LIST is one. If USER_DIR_LIST contained | |
| # a space anywhere, then the directories would not be searched. | |
| # | |
| BINPS=`echo ${BINPATHS} | tr ' ' '\n'` | |
| IFS=$IFSNL | |
| for DIR in ${BINPS} ${USER_DIR_LIST}; do | |
| test ! -d "${DIR}" && continue | |
| if [ -h "${DIR}" -a $HAVE_READLINK -eq 1 ]; then | |
| LINKDIR=`${READLINK_CMD} ${READLINK_OPT} "${DIR}"` | |
| else | |
| LINKDIR="${DIR}" | |
| fi | |
| if [ -z "`echo \"${PROP_DIR_LIST}\" | grep \"^${LINKDIR}$\"`" ]; then | |
| PROP_DIR_LIST="${PROP_DIR_LIST} | |
| ${LINKDIR}" | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| PROP_FILE_LIST="adduser amd awk basename bash bget cat chattr checkproc | |
| chkconfig chmod chown chroot cp cron csh curl cut date depmod df | |
| diff dirname dmesg dpkg dpkg-query du echo ed egrep elinks env fgrep | |
| file find fsck fuser GET grep groupadd groupdel groupmod groups grpck head id | |
| ifconfig ifdown ifstatus ifup inetd init insmod ip ipcs kallsyms kill | |
| killall ksyms kudzu last lastlog ldd less links locate logger login | |
| ls lsattr lsmod lsof lynx mail md5 md5sum mktemp mlocate modinfo | |
| modload modprobe modstat modunload more mount mv netstat newgrp | |
| newsyslog nologin passwd perl pgrep ping pkg pkgdb pkg_info pkill prelink ps pstree | |
| pwck pwd readlink rkhunter rmmod route rpm rsyslogd runcon runlevel sed sestatus sh | |
| sha1 sha1sum sha224 sha224sum sha256 sha256sum sha384 sha384sum sha512 | |
| sha512sum size skdet slocate sockstat sort ssh sshd stat strace strings su sudo | |
| sulogin sysctl syslogd systat tail tcpd telnet test top touch tr uname | |
| uniq useradd userdel usermod users vipw vmstat w watch wc wget whatis | |
| whereis which who whoami xinetd" | |
| # | |
| # We add in some extra commands to check depending on the O/S. | |
| # | |
| case "${OPERATING_SYSTEM}" in | |
| SunOS) | |
| PROP_FILE_LIST="${PROP_FILE_LIST} gawk gbasename gcat gchmod gchown | |
| gcksum gcp gcut gdate gdiff gdiff3 gdirname gdu gecho | |
| gegrep genv gfile gfind ggrep ggroups ghead gid glocate | |
| gls gmd5sum gmv gpwd gsed gsize gsort gstrings gsum | |
| gtail gtest gtouch guname guniq gusers gwc gwho gwhoami | |
| inetadm nawk truss unhide unhide-posix unhide-tcp" | |
| ;; | |
| FreeBSD|DragonFly) | |
| PROP_FILE_LIST="${PROP_FILE_LIST} fstat kldload kldstat kldunload procstat | |
| unhide unhide-posix unhide-tcp" | |
| ;; | |
| *BSD) | |
| PROP_FILE_LIST="${PROP_FILE_LIST} unhide unhide-posix unhide-tcp" | |
| ;; | |
| Linux) | |
| PROP_FILE_LIST="${PROP_FILE_LIST} unhide unhide-linux unhide-posix unhide-tcp numfmt" | |
| if [ -n "`echo \"${UNAME_R}\" | grep '^2\.6'`" ]; then | |
| PROP_FILE_LIST="${PROP_FILE_LIST} unhide-linux26" | |
| fi | |
| ;; | |
| Darwin) | |
| PROP_FILE_LIST="${PROP_FILE_LIST} shasum launchctl dscl gnumfmt" | |
| ;; | |
| esac | |
| # | |
| # Next we quickly loop through the user supplied list of files, | |
| # and ignore any that are already in the builtin list. At this | |
| # point we also change PROP_FILE_LIST from a space-separated | |
| # list to a newline-separated one. We have to do this because | |
| # we are about to add in the user-supplied pathnames. | |
| # | |
| PROP_FILE_LIST=`echo ${PROP_FILE_LIST} | tr ' ' '\n'` | |
| if [ -n "${USER_SIMPLE_FILE_LIST}" ]; then | |
| RKHTMPVAR="" | |
| IFS=$IFSNL | |
| for FNAME in ${USER_SIMPLE_FILE_LIST}; do | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| test -z "`echo \"${PROP_FILE_LIST}\" | grep \"^${FNAMEGREP}$\"`" && RKHTMPVAR="${RKHTMPVAR} | |
| ${FNAME}" | |
| done | |
| IFS=$RKHIFS | |
| USER_SIMPLE_FILE_LIST=`echo "${RKHTMPVAR}" | sed -e '/^$/d'` | |
| if [ -n "${USER_SIMPLE_FILE_LIST}" ]; then | |
| PROP_FILE_LIST="${PROP_FILE_LIST} | |
| ${USER_SIMPLE_FILE_LIST}" | |
| fi | |
| fi | |
| # | |
| # Now loop through the file list and look for any | |
| # symbolic links. If a link is found, then add on | |
| # the file and directory that the link points to. | |
| # | |
| if [ $HAVE_READLINK -eq 1 ]; then | |
| EXTRA_DIRS="" | |
| EXTRA_FILES="" | |
| IFS=$IFSNL | |
| for DIR in ${PROP_DIR_LIST}; do | |
| for FNAME in ${PROP_FILE_LIST}; do | |
| if [ -h "${DIR}/${FNAME}" ]; then | |
| RKHTMPVAR=`${READLINK_CMD} ${READLINK_OPT} "${DIR}/${FNAME}"` | |
| test ! -f "${RKHTMPVAR}" && continue | |
| # | |
| # Get the link target directory name. | |
| # | |
| test -n "${DIRNAME_CMD}" && LINKDIR=`${DIRNAME_CMD} "${RKHTMPVAR}"` || LINKDIR=`echo "${RKHTMPVAR}" | sed -e 's:/[^/]*$::'` | |
| # | |
| # Now see if we already have the directory listed. | |
| # If not, then we add it on. | |
| # | |
| RKHTMPVAR3="${PROP_DIR_LIST} | |
| ${EXTRA_DIRS}" | |
| if [ -z "`echo \"${RKHTMPVAR3}\" | grep \"^${LINKDIR}$\"`" ]; then | |
| EXTRA_DIRS="${EXTRA_DIRS} | |
| ${LINKDIR}" | |
| fi | |
| # | |
| # Now get the link target file name. | |
| # | |
| LINKFNAME=`echo "${RKHTMPVAR}" | sed -e 's:^.*/::'` | |
| FNAMEGREP=`echo "${LINKFNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| # | |
| # And finally check if we already have it listed. | |
| # | |
| RKHTMPVAR3="${PROP_FILE_LIST} | |
| ${EXTRA_FILES}" | |
| if [ -z "`echo \"${RKHTMPVAR3}\" | grep \"^${FNAMEGREP}$\"`" ]; then | |
| EXTRA_FILES="${EXTRA_FILES} | |
| ${LINKFNAME}" | |
| fi | |
| fi | |
| done | |
| done | |
| IFS=$RKHIFS | |
| EXTRA_DIRS=`echo "${EXTRA_DIRS}" | sed -e '/^$/d'` | |
| EXTRA_FILES=`echo "${EXTRA_FILES}" | sed -e '/^$/d'` | |
| test -n "${EXTRA_DIRS}" && PROP_DIR_LIST="${PROP_DIR_LIST} | |
| ${EXTRA_DIRS}" | |
| test -n "${EXTRA_FILES}" && PROP_FILE_LIST="${PROP_FILE_LIST} | |
| ${EXTRA_FILES}" | |
| fi | |
| PROP_FILE_LIST_TOTAL=`echo "${PROP_FILE_LIST}" | wc -l | tr -d ' '` | |
| return | |
| } | |
| check_test() { | |
| # | |
| # This function will check whether a given test name should | |
| # be run or not. It returns 0 if the test is to be run, | |
| # and 1 if it is not. | |
| # | |
| if [ "${ENABLE_TESTS}" = "all" -o -n "`echo \" ${ENABLE_TESTS} \" | grep \" $1 \"`" ]; then | |
| if [ "${DISABLE_TESTS}" = "none" -o -z "`echo \" ${DISABLE_TESTS} \" | grep \" $1 \"`" ]; then | |
| return 0 | |
| fi | |
| fi | |
| return 1 | |
| } | |
| display_tests() { | |
| # | |
| # This function is used to simply output all the available | |
| # tests and test group names. If a group name itself contains | |
| # a group name, then that second group name is omitted. It | |
| # could be confusing if it was included. | |
| # | |
| RKHTMPVAR2=`echo "all none ${KNOWN_TESTS}" | tr ' ' '\n' | sort | tr '\n' ' '` | |
| GROUPED_TESTS=`echo "${GROUPED_TESTS}" | tr ' ' '\n' | sort | tr '\n' ' '` | |
| display --to SCREEN --type PLAIN --nl LIST_TESTS | |
| while test -n "${RKHTMPVAR2}"; do | |
| STR=`echo ${RKHTMPVAR2} | cut -d' ' -f1-6` | |
| RKHTMPVAR2=`echo ${RKHTMPVAR2} | cut -d' ' -f7-` | |
| echo " ${STR}" | |
| test "${STR}" = "${RKHTMPVAR2}" && RKHTMPVAR2="" | |
| done | |
| display --to SCREEN --type PLAIN --nl LIST_GROUPED_TESTS | |
| # | |
| # Sort out the maximum group name length, so we can do some | |
| # simple formatting of the output. | |
| # | |
| MAX=0 | |
| for STR in ${GROUPED_TESTS}; do | |
| LEN=`echo "${STR}" | cut -d: -f1 | wc -c | tr -d ' '` | |
| test $LEN -gt $MAX && MAX=$LEN | |
| done | |
| # | |
| # Now loop through the group names. | |
| # | |
| RKHTMPVAR2=" `echo ${GROUPED_TESTS}`" | |
| for STR in ${GROUPED_TESTS}; do | |
| TEST_NAMES="" | |
| GROUP_NAME=`echo "${STR}" | cut -d: -f1` | |
| # | |
| # Add on spaces to expand the group name to the maximum. | |
| # | |
| LEN=`echo "${GROUP_NAME}" | wc -c | tr -d ' '` | |
| LEN=`expr $MAX - $LEN` | |
| test $LEN -gt 0 && GROUP_NAME="${GROUP_NAME} `echo \"${BLANK_LINE}\" | cut -d' ' -f1-$LEN`" | |
| # | |
| # Check through the list of tests for this group name. | |
| # If the test name is a group name itself, then go to | |
| # the next test name, otherwise add it to our list of | |
| # test names. | |
| # | |
| for TEST in `echo "${STR}" | cut -d: -f2- | tr ':' ' '`; do | |
| RKHTMPVAR=`echo "${RKHTMPVAR2}" | grep " ${TEST}:"` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| TEST_NAMES="${TEST_NAMES}:${TEST}" | |
| else | |
| continue | |
| fi | |
| done | |
| # | |
| # Finally, sort our list of test names and display them. | |
| # | |
| TEST_NAMES=`echo "${TEST_NAMES}" | sed -e 's/^://' | tr ':' '\n' | sort | tr '\n' ' '` | |
| echo " ${GROUP_NAME} => ${TEST_NAMES}" | |
| done | |
| return | |
| } | |
| display_languages() { | |
| # | |
| # This function is used to simply output all the available | |
| # languages in a basic format of 10 per line. | |
| # | |
| KNOWN_LANGS=`ls -1 ${DB_PATH}/i18n 2>/dev/null | sort` | |
| display --to SCREEN --type PLAIN --nl LIST_LANGS | |
| while test -n "${KNOWN_LANGS}"; do | |
| STR=`echo ${KNOWN_LANGS} | cut -d' ' -f1-10` | |
| KNOWN_LANGS=`echo ${KNOWN_LANGS} | cut -d' ' -f11-` | |
| echo " ${STR}" | |
| test "${STR}" = "${KNOWN_LANGS}" && KNOWN_LANGS="" | |
| done | |
| return | |
| } | |
| display_perl_modules() { | |
| # | |
| # This function is used to display the status of | |
| # the installed perl modules which may be required. | |
| # | |
| display --to SCREEN --type PLAIN --nl LIST_PERL | |
| for MODNAME in perl ${LIST_MODULES}; do | |
| if [ "${MODNAME}" = "perl" ]; then | |
| MODNAME="perl command" | |
| test -n "${PERL_CMD}" && MOD_INSTALLED="" || MOD_INSTALLED="NOT installed" | |
| else | |
| MOD_INSTALLED=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" ${MODNAME} 2>/dev/null | grep 'NOT installed'` | |
| fi | |
| MODLEN=`echo "${MODNAME}" | wc -c | tr -d ' '` | |
| NUM_SPACES=`expr 28 - ${MODLEN}` | |
| test $NUM_SPACES -lt 1 && NUM_SPACES=1 | |
| SPACES=`echo "${BLANK_LINE}" | cut -c1-$NUM_SPACES` | |
| if [ -z "${MOD_INSTALLED}" ]; then | |
| echo $ECHOOPT " ${MODNAME}${SPACES}Installed" | |
| else | |
| echo $ECHOOPT " ${MODNAME}${SPACES} MISSING" | |
| fi | |
| test "${MODNAME}" = "perl command" -a -z "${PERL_CMD}" && break | |
| done | |
| return | |
| } | |
| display_propfiles() { | |
| # | |
| # This function is used to display the list of files which | |
| # would be searched for when using the '--propupd' function. | |
| # | |
| # Get any user-supplied files and directories. | |
| get_user_fileprop_list | |
| # Get the builtin list of files and directories. | |
| set_file_prop_dirs_files | |
| # Create the file of entries used by the '--propupd' function. | |
| create_rkh_file_prop_list | |
| # Finally just dump out the list of file names. | |
| ${AWK_CMD} -F'/' '{ print $NF }' "${RKH_FILEPROP_LIST}" | sort | uniq | |
| return | |
| } | |
| display_rootkits() { | |
| # | |
| # This function is used to simply output all the rootkit | |
| # names which rkhunter will check for. | |
| # | |
| RKHTMPVAR2=`echo ${KNOWN_ROOTKITS} | sed -e 's/^,*//; s/,$//'` | |
| display --to SCREEN --type PLAIN --nl LIST_RTKTS | |
| while test -n "${RKHTMPVAR2}"; do | |
| STR=`echo ${RKHTMPVAR2} | cut -d',' -f1-6` | |
| RKHTMPVAR2=`echo ${RKHTMPVAR2} | cut -d',' -f7-` | |
| if [ "${STR}" = "${RKHTMPVAR2}" -o -z "${RKHTMPVAR2}" ]; then | |
| RKHTMPVAR2="" | |
| else | |
| STR="${STR}," | |
| fi | |
| echo " ${STR}" | |
| done | |
| return | |
| } | |
| get_lock() { | |
| # | |
| # This function attempts to get the lock file. If it cannot | |
| # get the lock then it waits for 10 seconds, and then tries | |
| # again. It repeats this until the timeout has passed. | |
| # | |
| # We cannot log anything at this time, but we can use | |
| # 'display' to display messages on the users screen. | |
| # | |
| RKHTMPVAR=0 | |
| while test $RKHTMPVAR -lt $LOCK_TIMEOUT; do | |
| if [ -f "${LOCKDIR}/rkhunter.LCK" ]; then | |
| test $SHOW_LOCK_MSGS -eq 1 -a $RKHTMPVAR -eq 0 && display --to SCREEN --type PLAIN --nonl LOCK_WAIT | |
| sleep 10; | |
| RKHTMPVAR=`expr ${RKHTMPVAR} + 10` | |
| test $SHOW_LOCK_MSGS -eq 1 && display --to SCREEN --type PLAIN --nonl NAME "..${RKHTMPVAR}" | |
| else | |
| break | |
| fi | |
| done | |
| if [ $RKHTMPVAR -lt $LOCK_TIMEOUT -o ! -f "${LOCKDIR}/rkhunter.LCK" ]; then | |
| echo "$$" >"${LOCKDIR}/rkhunter.LCK" | |
| test $SHOW_LOCK_MSGS -eq 1 -a $RKHTMPVAR -gt 0 -a $NOTTY -eq 0 && echo "" | |
| # | |
| # We handle any subsequent exit conditions by setting a trap. | |
| # | |
| trap "rm -f \"${LOCKDIR}/rkhunter.LCK\" >/dev/null 2>&1" 0 >/dev/null 2>&1 | |
| else | |
| # | |
| # We need to be careful here. We do not want to display the message if the user | |
| # has explicitly requested not to, but we must display it if the user has set | |
| # the '--report-warnings-only' option (we treat it as a warning), or the | |
| # '--cronjob' option. If we did not, then the user may think that rkhunter has | |
| # run and that there were no warnings. If the user used the '--quiet' option, | |
| # then this message won't be displayed. However, that is okay because they | |
| # should be checking the return-code. | |
| # | |
| if [ $SHOWWARNINGSONLY -eq 1 -o $CRONJOB -eq 1 ]; then | |
| NOTTY=0 | |
| RKHTMPVAR="" | |
| else | |
| RKHTMPVAR="--nl" | |
| fi | |
| test $SHOW_LOCK_MSGS -eq 1 -o $NOTTY -eq 0 && display --to SCREEN --type PLAIN ${RKHTMPVAR} LOCK_FAIL | |
| exit 1 | |
| fi | |
| return | |
| } | |
| help() { | |
| # | |
| # This function outputs the help menu. | |
| # | |
| echo $ECHOOPT "" | |
| echo $ECHOOPT "Usage: rkhunter {--check | --unlock | --update | --versioncheck |" | |
| echo $ECHOOPT " --propupd [{filename | directory | package name},...] |" | |
| echo $ECHOOPT " --list [{tests | {lang | languages} | rootkits | perl | propfiles}] |" | |
| echo $ECHOOPT " --config-check | --version | --help} [options]" | |
| echo $ECHOOPT "" | |
| echo $ECHOOPT "Current options are:" | |
| echo $ECHOOPT " --append-log Append to the logfile, do not overwrite" | |
| echo $ECHOOPT " --bindir <directory>... Use the specified command directories" | |
| echo $ECHOOPT " -c, --check Check the local system" | |
| echo $ECHOOPT " -C, --config-check Check the configuration file(s), then exit" | |
| echo $ECHOOPT " --cs2, --color-set2 Use the second color set for output" | |
| echo $ECHOOPT " --configfile <file> Use the specified configuration file" | |
| echo $ECHOOPT " --cronjob Run as a cron job" | |
| echo $ECHOOPT " (implies -c, --sk and --nocolors options)" | |
| echo $ECHOOPT " --dbdir <directory> Use the specified database directory" | |
| echo $ECHOOPT " --debug Debug mode" | |
| echo $ECHOOPT " (Do not use unless asked to do so)" | |
| echo $ECHOOPT " --disable <test>[,<test>...] Disable specific tests" | |
| echo $ECHOOPT " (Default is to disable no tests)" | |
| echo $ECHOOPT " --display-logfile Display the logfile at the end" | |
| echo $ECHOOPT " --enable <test>[,<test>...] Enable specific tests" | |
| echo $ECHOOPT " (Default is to enable all tests)" | |
| echo $ECHOOPT " --hash {MD5 | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 |" | |
| echo $ECHOOPT " NONE | <command>} Use the specified file hash function" | |
| echo $ECHOOPT " (Default is SHA256)" | |
| echo $ECHOOPT " -h, --help Display this help menu, then exit" | |
| echo $ECHOOPT " --lang, --language <language> Specify the language to use" | |
| echo $ECHOOPT " (Default is English)" | |
| echo $ECHOOPT " --list [tests | languages | List the available test names, languages," | |
| echo $ECHOOPT " rootkits | perl | rootkit names, perl module status" | |
| echo $ECHOOPT " propfiles] or file properties database, then exit" | |
| echo $ECHOOPT " -l, --logfile [file] Write to a logfile" | |
| echo $ECHOOPT " (Default is $DFLT_LOGFILE)" | |
| echo $ECHOOPT " --noappend-log Do not append to the logfile, overwrite it" | |
| echo $ECHOOPT " --nocf Do not use the configuration file entries" | |
| echo $ECHOOPT " for disabled tests (only valid with --disable)" | |
| echo $ECHOOPT " --nocolors Use black and white output" | |
| echo $ECHOOPT " --nolog Do not write to a logfile" | |
| echo $ECHOOPT "--nomow, --no-mail-on-warning Do not send a message if warnings occur" | |
| echo $ECHOOPT " --ns, --nosummary Do not show the summary of check results" | |
| echo $ECHOOPT " --novl, --no-verbose-logging No verbose logging" | |
| echo $ECHOOPT " --pkgmgr {RPM | DPKG | BSD | Use the specified package manager to obtain" | |
| echo $ECHOOPT " BSDng | SOLARIS | or verify file property values." | |
| echo $ECHOOPT " NONE} (Default is NONE)" | |
| echo $ECHOOPT " --propupd [file | directory | Update the entire file properties database," | |
| echo $ECHOOPT " package]... or just for the specified entries" | |
| echo $ECHOOPT " -q, --quiet Quiet mode (no output at all)" | |
| echo $ECHOOPT " --rwo, --report-warnings-only Show only warning messages" | |
| echo $ECHOOPT " --sk, --skip-keypress Don't wait for a keypress after each test" | |
| echo $ECHOOPT " --summary Show the summary of system check results" | |
| echo $ECHOOPT " (This is the default)" | |
| echo $ECHOOPT " --syslog [facility.priority] Log the check start and finish times to syslog" | |
| echo $ECHOOPT " (Default level is $SYSLOG_DFLT_PRIO)" | |
| echo $ECHOOPT " --tmpdir <directory> Use the specified temporary directory" | |
| echo $ECHOOPT " --unlock Unlock (remove) the lock file" | |
| echo $ECHOOPT " --update Check for updates to database files" | |
| echo $ECHOOPT " --vl, --verbose-logging Use verbose logging (on by default)" | |
| echo $ECHOOPT " -V, --version Display the version number, then exit" | |
| echo $ECHOOPT " --versioncheck Check for latest version of program" | |
| echo $ECHOOPT " -x, --autox Automatically detect if X is in use" | |
| echo $ECHOOPT " -X, --no-autox Do not automatically detect if X is in use" | |
| echo $ECHOOPT "" | |
| return | |
| } | |
| ###################################################################### | |
| # | |
| # Initialisation | |
| # | |
| ###################################################################### | |
| # | |
| # Unfortunately, for the Korn shell if we are debugging then | |
| # we need to enable tracing in each of the functions. | |
| # | |
| if [ $DEBUG_OPT -eq 1 -a "${MYSHELL}" = "ksh" ]; then | |
| RKHTMPVAR=`typeset +f` | |
| for RKHTMPVAR2 in ${RKHTMPVAR}; do | |
| typeset -ft ${RKHTMPVAR2} | |
| done | |
| fi | |
| # | |
| # We reset the SIGPIPE signal to its default | |
| # to try and avoid any output write errors. | |
| # | |
| trap - 13 >/dev/null 2>&1 | |
| # | |
| # Initialise the variables used throughout the program. | |
| # | |
| RKH_VER_MAJ="1" | |
| RKH_VER_MIN="4" | |
| PROGRAM_NAME="Rootkit Hunter" | |
| PROGRAM_version="${RKH_VER_MAJ}.${RKH_VER_MIN}.6" | |
| PROGRAM_copyright_owner="Michael Boelen" | |
| PROGRAM_copyright="Copyright (c) 2003-2018, ${PROGRAM_copyright_owner}" | |
| PROGRAM_blurb=" | |
| This software was developed by the ${PROGRAM_NAME} project team. | |
| Please review your rkhunter configuration files before using. | |
| Please review the documentation before posting bug reports or questions. | |
| To report bugs, provide patches or comments, please go to: | |
| http://rkhunter.sourceforge.net | |
| To ask questions about rkhunter, please use the rkhunter-users mailing list. | |
| Note this is a moderated list: please subscribe before posting. | |
| ${PROGRAM_NAME} 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 the LICENSE file for details. | |
| " | |
| PROGRAM_license=" | |
| ${PROGRAM_NAME} ${PROGRAM_version}, ${PROGRAM_copyright} | |
| ${PROGRAM_blurb} | |
| " | |
| LOGGER_TAG="rkhunter" | |
| LEAVE=0 | |
| ERRCODE=0 | |
| # Set to run as a cron job. | |
| CRONJOB=0 | |
| CHECK=0 | |
| # Set to display the logfile at the end. | |
| CATLOGFILE=0 | |
| NOLOG=0 | |
| RKHLOGFILE="" | |
| DFLT_LOGFILE="/var/log/rkhunter.log" | |
| # Set to have the logfile appended to rather than overwritten. | |
| APPEND_LOG=0 | |
| APPEND_OPT=0 | |
| # Set to have the logfile copied if there was an error. | |
| COPY_LOG_ON_ERROR=0 | |
| # Set to have rkhunter start/finish messages, and warnings, | |
| # logged to syslog. The priority/severity can be set on the | |
| # command-line or in the configuration file. | |
| USE_SYSLOG="" | |
| SYSLOG_DFLT_PRIO="authpriv.notice" | |
| # By default do not send a mail-on-warning message. | |
| NOMOW=0 | |
| MAILONWARNING="" | |
| HASH_FUNC="" | |
| OLD_HASH_FUNC="" | |
| PKGMGR="" | |
| OLD_PKGMGR="" | |
| OLD_ATTRUPD="" | |
| HASH_OPT=0 | |
| SHA_SIZE=0 | |
| HASH_FLD_IDX=1 | |
| PROP_DIR_LIST="" | |
| PROP_FILE_LIST="" | |
| PROP_FILE_LIST_COUNT=0 | |
| PROP_FILE_LIST_TOTAL=0 | |
| PRELINKED=0 | |
| PRELINK_CMD="" | |
| PRELINK_HASH="" | |
| PKGMGR_MD5_HASH="" | |
| PKGMGR_SHA_HASH="" | |
| MD5_CMD="" | |
| EPOCH_DATE_CMD="" | |
| PKGMGRNOVRFY="" | |
| UPDATE=0 | |
| PROP_UPDATE=0 | |
| PROPUPD_OPT="" | |
| VERSIONCHECK=0 | |
| # By default use coloured output. | |
| COLORS=1 | |
| CLRSET2=0 | |
| # Are whitelisted results to be shown as white? | |
| WLIST_IS_WHITE=0 | |
| # Set to automatically detect if X is in use, and | |
| # hence use the second colour set. | |
| AUTO_X_DTCT=0 | |
| AUTO_X_OPT=0 | |
| # Set to be quiet. No output, but the return code will be set. | |
| QUIET=0 | |
| # Set to only show warnings. | |
| SHOWWARNINGSONLY=0 | |
| # This will be set if the file properties hash value check | |
| # or the file attributes check is to be performed. | |
| HASH_CHECK_ENABLED=0 | |
| SKIP_HASH_MSG=0 | |
| # Users can reset this to a new temporary directory. | |
| RKHTMPDIR="" | |
| # Users can reset this to a new database directory. | |
| DB_PATH="" | |
| # Users can reset this to a new configuration file. | |
| CONFIGFILE="" | |
| # Users cannnot reset this. The local config file must | |
| # be in the same directory as the main config file. | |
| LOCALCONFIGFILE="" | |
| # Users cannot reset this. The rkhunter.d directory must | |
| # be in the same directory as the main config file. | |
| LOCALCONFIGDIR="" | |
| # Users cannot reset this. The rkhunter.d config files | |
| # can only be stored in the local config directory. | |
| LOCALCONFDIRCOUNT=0 | |
| LOCALCONFDIRFILES="" | |
| # This will be set similar to the current root PATH. Users can | |
| # include new command directories to use as well. | |
| BINPATHS="" | |
| DFLT_BINPATHS="/bin /usr/bin /sbin /usr/sbin /usr/local/bin /usr/local/sbin /usr/libexec /usr/local/libexec" | |
| BINDIR_OPT=0 | |
| # This will be set if any of the command directories is a symbolic link. | |
| BINISLINK=0 | |
| # Default 'id' and 'awk' commands. Solaris may reset these. | |
| ID_CMD='id' | |
| AWK_CMD='awk' | |
| # Set if we don't want to wait for a keypress after each test. | |
| SKIP_KEY_PRESS=0 | |
| # Does 'grep' need an extra option to check binary files? | |
| GREP_OPT="" | |
| # Set the O/S type if necessary. | |
| BSDOS=0 | |
| SUNOS=0 | |
| IRIXOS=0 | |
| MACOSX=0 | |
| LINUXOS=0 | |
| case "${OPERATING_SYSTEM}" in | |
| Linux) | |
| LINUXOS=1 | |
| GREP_OPT="-a" | |
| ;; | |
| *BSD|DragonFly) | |
| BSDOS=1 | |
| HASH_FLD_IDX=4 | |
| GREP_OPT="-a" | |
| ;; | |
| SunOS) | |
| SUNOS=1 | |
| ;; | |
| IRIX*) | |
| IRIXOS=1 | |
| ;; | |
| Darwin) | |
| MACOSX=1 | |
| ;; | |
| esac | |
| # This will be set if the local host or O/S has changed in some way. | |
| OS_CHANGED=0 | |
| # By default we want a warning if the O/S has changed. | |
| WARN_ON_OS_CHANGE=1 | |
| # If set, then automatically perform a properties update if the O/S changes. | |
| UPDT_ON_OS_CHANGE=0 | |
| # These SSH options can only be set in the configuration file. | |
| ALLOW_SSH_PROT_V1=0 | |
| ALLOW_SSH_ROOT_USER="" | |
| SSH_CONFIG_DIR="" | |
| # These syslog options can only be set in the configuration file. | |
| ALLOW_SYSLOG_REMOTE_LOGGING=0 | |
| SYSLOG_CONFIG_FILE="" | |
| # Set check counters to be used by the summary. | |
| ROOTKIT_COUNT=0 | |
| ROOTKIT_FAILED_COUNT=0 | |
| ROOTKIT_FAILED_NAMES="" | |
| PROP_FAILED_COUNT=0 | |
| SUMMARY_PROP_REQCMDS=0 | |
| APPS_COUNT=0 | |
| APPS_TOTAL_COUNT=0 | |
| APPS_FAILED_COUNT=0 | |
| # Timers for the system check. | |
| BEGINTIME=0 | |
| TOTAL_SCANTIME="" | |
| # This will be set if a warning message is logged. | |
| WARNING_COUNT=0 | |
| # This will be set to the kernel symbols file used in some checks. | |
| KSYMS_FILE="" | |
| # Record for logging the command-line being used. | |
| CMD_LINE="$0 $*" | |
| # Create a spaced-separated PATH variable. | |
| RKHROOTPATH=`echo ${PATH} | tr ':' ' '` | |
| # List of commands used during RKH. If a command does not exist, then | |
| # the code may use an alternative method. | |
| CMDLIST="basename diff dirname file find ifconfig ip ipcs ldd lsattr lsmod lsof mktemp netstat numfmt perl pgrep ps pwd readlink stat strings" | |
| # Commands that are required to exist for RKH to run. The absolutely | |
| # required commands are tested early on using just the root PATH. Then | |
| # BINDIR is checked, and finally the rest of the commands are then | |
| # checked using the new PATH from BINDIR. | |
| ABSOLUTELY_REQUIRED_CMDS="cut grep sed tail tr" | |
| REQCMDS="awk cat chmod chown cp cut date grep head ls mv sed sort tail touch tr uname uniq wc" | |
| # This will be set to a list of commands that have been disabled. | |
| DISABLED_CMDS="" | |
| # List of commands used to download files from the web. This list is | |
| # used by the '--update' and '--versioncheck' options. Preferred commands | |
| # are listed first. This can be overridden by the config file. | |
| WEBCMDLIST="wget curl elinks links lynx bget GET" | |
| RKHWEBCMD="" | |
| RKHWEBCMD_OPTS="" | |
| RKHWEBCMD_BASE="" | |
| HOST_NAME="" | |
| # This is the return code for the program actions - update, check, etc. | |
| # Its value may either be 0 (no error) or 1 (an error occurred). | |
| # The '--versioncheck' option may set the return code to 2 to | |
| # indicate that an update is available. | |
| # The '--update' option may set the return code to 2 to | |
| # indicate that an update occurred. | |
| RET_CODE=0 | |
| # Initially there is no language, this will be set later. | |
| LANGUAGE="" | |
| UPDATE_LANG="" | |
| LOCALE_CMD="" | |
| ICONV_CMD="" | |
| RKHCHRMAP="" | |
| RKHCHKLOCALE=0 | |
| # A space-separated list of test names we recognise. | |
| KNOWN_TESTS="strings properties hashes scripts immutable attributes | |
| deleted_files packet_cap_apps apps rootkits known_rkts | |
| additional_rkts malware local_host network passwd_changes | |
| group_changes possible_rkt_files possible_rkt_strings | |
| system_commands shared_libs shared_libs_path running_procs | |
| hidden_procs trojans os_specific startup_malware | |
| startup_files group_accounts system_configs system_configs_ssh | |
| system_configs_syslog filesystem suspscan ports hidden_ports | |
| promisc loaded_modules avail_modules login_backdoors | |
| sniffer_logs tripwire susp_dirs ipc_shared_mem" | |
| # A space-separated list of test 'group names'. This list allows test | |
| # names to be grouped together. For example, 'system_commands' can include | |
| # the specific tests of 'strings' and 'hashes'. Both test | |
| # group names, and specific test names, can be used with the test | |
| # enable/disable options. In this list group names are colon-separated | |
| # from the specific test names. | |
| # | |
| GROUPED_TESTS="system_commands:properties:strings:hashes:scripts:shared_libs:shared_libs_path:immutable:attributes | |
| properties:hashes:scripts:immutable:attributes | |
| shared_libs:shared_libs_path | |
| rootkits:known_rkts:additional_rkts:possible_rkt_files:possible_rkt_strings:malware:running_procs:hidden_procs:deleted_files:trojans:os_specific:suspscan:loaded_modules:avail_modules:login_backdoors:sniffer_logs:tripwire:susp_dirs:ipc_shared_mem | |
| additional_rkts:possible_rkt_files:possible_rkt_strings | |
| network:packet_cap_apps:ports:hidden_ports:promisc | |
| malware:running_procs:hidden_procs:deleted_files:suspscan:login_backdoors:sniffer_logs:tripwire:susp_dirs:ipc_shared_mem | |
| local_host:startup_files:passwd_changes:group_changes:startup_malware:group_accounts:system_configs:filesystem:system_configs_ssh:system_configs_syslog | |
| startup_files:startup_malware | |
| os_specific:loaded_modules:avail_modules | |
| group_accounts:passwd_changes:group_changes | |
| system_configs:system_configs_ssh:system_configs_syslog" | |
| # A comma-separated list of rootkits we check for. | |
| # NOTE: This is a COMMA separated list. Any single quotes need to be handled specially - i.e. | |
| # put between double-quotes. | |
| KNOWN_ROOTKITS='55808 Trojan - Variant A, AjaKit, aPa Kit, Adore, Apache Worm, Ambient (ark), | |
| Balaur, BeastKit, beX2, BOBKit, Boonana (Koobface.A), cb, CiNIK Worm (Slapper.B variant), CX, | |
| Danny-Boy'"'"'s Abuse Kit, Devil, Diamorphine LKM, Dica, Dreams, Duarawkz, Ebury, Enye LKM, Flea Linux, FreeBSD, Fu, | |
| Fuck`it, GasKit, Heroin LKM, HjC Kit, ignoKit, iLLogiC, Inqtana-A, Inqtana-B, Inqtana-C, | |
| IntoXonia-NG, Irix, Jynx, Jynx2, KBeast, Keydnap, Kitko, Knark, Komplex, ld-linuxv.so, Li0n Worm, Lockit/LJK2, Mokes, | |
| Mood-NT, MRK, Ni0, Ohhara, Optic Kit (Tux), OSXRK, Oz, Phalanx, Phalanx2, Portacelo, Proton, R3dstorm Toolkit, | |
| RH-Sharpe'"'"'s, RSHA'"'"'s, Scalper Worm, Shutdown, SHV4, SHV5, Sin, SInAR, Slapper, | |
| Sneakin, Solaris Wanuk, Spanish, Suckit, SunOS / NSDAP, SunOS Rootkit, Superkit, TBD (Telnet BackDoor), | |
| TeLeKiT, Togroot, T0rn, trNkit, Trojanit Kit, Turtle2, Tuxtendo, URK, Vampire, VcKit, Volc, w00tkit, | |
| weaponX, Xzibit, X-Org SunOS, zaRwT.KiT, ZK' | |
| # A space-separated list of perl modules that may be required. | |
| LIST_MODULES="File::stat Getopt::Long Crypt::RIPEMD160 Digest::MD5 Digest::SHA Digest::SHA1 Digest::SHA256 | |
| Digest::SHA::PurePerl Digest::Whirlpool LWP URI HTTP::Status HTTP::Date Socket Carp" | |
| # A list of configuration options which are space-separated lists. | |
| SPACE_LIST_OPTS="ALLOWIPCPID ALLOWIPCUSER ALLOWPROMISCIF APP_WHITELIST BINDIR DISABLE_TESTS EMPTY_LOGFILES | |
| ENABLE_TESTS IGNORE_PRELINK_DEP_ERR INETD_ALLOWED_SVC MAIL-ON-WARNING MISSING_LOGFILES | |
| PORT_WHITELIST PWDLESS_ACCOUNTS SHARED_LIB_WHITELIST STARTUP_PATHS SUSPSCAN_DIRS | |
| SYSLOG_CONFIG_FILE UID0_ACCOUNTS UNHIDE_TESTS UNHIDETCP_OPTS UPDATE_LANG | |
| XINETD_ALLOWED_SVC" | |
| SPACE_LIST_OPTS=" `echo ${SPACE_LIST_OPTS}` " | |
| # A list of configuration options which are newline-separated lists. | |
| NEWLINE_LIST_OPTS="ALLOWDEVFILE ALLOWHIDDENDIR ALLOWHIDDENFILE ALLOWPROCDELFILE ALLOWIPCPROC | |
| ALLOWPROCLISTEN ATTRWHITELIST EXCLUDE_USER_FILEPROP_FILES_DIRS EXISTWHITELIST | |
| IMMUTWHITELIST PKGMGR_NO_VRFY PORT_PATH_WHITELIST RTKT_DIR_WHITELIST | |
| RTKT_FILE_WHITELIST SCRIPTWHITELIST SUSPSCAN_WHITELIST USER_FILEPROP_FILES_DIRS | |
| WRITEWHITELIST" | |
| NEWLINE_LIST_OPTS=" `echo ${NEWLINE_LIST_OPTS}` " | |
| # The program defaults of which tests to perform will be set later. | |
| ENABLE_TESTS="" | |
| DISABLE_TESTS="" | |
| CL_ENABLE_TESTS="" | |
| CL_DISABLE_TESTS="" | |
| CONFIG_DISABLE_TESTS="" | |
| # These get set if the '--enable' or '--disable' command-line options have been used. | |
| ENDIS_OPT=0 | |
| ENABLE_OPT=0 | |
| # This gets set to zero if the '--nocf' command-line option is used. | |
| USECF=1 | |
| # This gets set if the '--list' command-line option is used. | |
| LIST_OPT="" | |
| # Space-filled line used for the display function. | |
| BLANK_LINE=" " | |
| # Initially say that we are connected to a terminal. | |
| NOTTY=0 | |
| # By default show the system check summary. | |
| SHOW_SUMMARY=1 | |
| SHOW_SUMMARY_OPT=0 | |
| SHOW_SUMMARY_TIME=3 | |
| SHOW_SUMMARY_WARNINGS_NUMBER=0 | |
| # By default log most things that are checked. | |
| VERBOSE_LOGGING=1 | |
| # We copy the original IFS value, and set RKHIFS to space, tab, newline. | |
| # IFSNL is set to just a newline. | |
| ORIGIFS=$IFS | |
| RKHIFS=" | |
| " | |
| IFSNL=" | |
| " | |
| IFS=$RKHIFS | |
| # No default set for the system startup files and directories. | |
| STARTUP_PATHS="" | |
| STARTUP_PATHS_LOGGED=0 | |
| # Set a default for the inetd configuration file. | |
| INETD_CONF_PATH="/etc/inetd.conf" | |
| INETDALLOWEDSVCS="" | |
| # Set a default for the xinetd configuration file. | |
| XINETD_CONF_PATH="/etc/xinetd.conf" | |
| XINETDALLOWEDSVCS="" | |
| # Set if only the '--update' option is used. | |
| UPDATE_ONLY=0 | |
| # Set if UPDATE_ONLY is set, and some language files are missing. | |
| RKHLANGUPDT=0 | |
| # By default we rotate the mirrors in the mirrors.dat file, | |
| # and we update the file when the '--update' option is used. | |
| # The default MIRRORS_MODE is set such that we use both local | |
| # and remote mirrors. | |
| ROTATE_MIRRORS=1 | |
| UPDATE_MIRRORS=1 | |
| MIRRORS_MODE=0 | |
| # Set the default suspscan settings. | |
| SUSPSCAN_DEBUG=0 | |
| SUSPSCAN_DFLT_DIRS="/tmp /var/tmp" | |
| SUSPSCAN_DFLT_TMP="/dev/shm" | |
| SUSPSCAN_DFLT_THRESH=200 | |
| SUSPSCAN_DFLT_MAXSIZE=1024000 | |
| SUSPSCAN_WL_OPT="" | |
| # SELinux runcon usage as determined by get_if_prelinked. | |
| USE_RUNCON=0 | |
| SELINUX_ENABLED=0 | |
| # These get set if any network ports are to be whitelisted. | |
| PORT_WHITELIST="" | |
| PORT_PATH_WHITELIST="" | |
| PORT_WHITELIST_ALL_TRUSTED=0 | |
| # This will be set to the shadow file location if required. | |
| SHADOW_FILE="" | |
| HAVE_TCB_SHADOW=0 | |
| # The O/S 'release' file location. | |
| OS_VERSION_FILE="" | |
| # By default no rootkit files or directories are whitelisted. | |
| RTKT_DIR_WHITELIST="" | |
| RTKT_FILE_WHITELIST="" | |
| # The full pathname of the 'rkhunter.dat' file. | |
| RKHDAT_FILE="" | |
| # The full pathname of the 'rkhunter_prop_list.dat' file. | |
| RKH_FILEPROP_LIST="" | |
| # This gets set if we have a working readlink command. | |
| HAVE_READLINK=0 | |
| # By default no commands are to be exempt from dependency errors. | |
| PRELINK_DEP_ERR_CMDS="" | |
| # User provided files/dirs for the file properties check. | |
| USER_FILE_LIST="" | |
| USER_SIMPLE_FILE_LIST="" | |
| USER_DIR_LIST="" | |
| USER_EXCLUDE_PROP="" | |
| # This gets set if any shared libraries are to be whitelisted. | |
| SHARED_LIB_WHITELIST="" | |
| # If used, these lock values must be set in the config file. | |
| USE_LOCKING=0 | |
| LOCKDIR="" | |
| LOCK_TIMEOUT=0 | |
| SHOW_LOCK_MSGS=1 | |
| # This gets set if the '--unlock' command-line option is used. | |
| UNLOCK=0 | |
| # This gets set if any files or directories need | |
| # whitelisting from 'existence' checks. | |
| EXISTWHITELIST="" | |
| # This will be set if we are just doing a config file check. | |
| CONFIG_CHECK=0 | |
| # Network interface whitelist. | |
| IFWLIST="" | |
| # This will be set to any allowed processes listening on the network. | |
| ALLOWPROCLIST_OPT="" | |
| # This option will be set if the shell globstar option is to be set. | |
| GLOBSTAR=0 | |
| # The default value for the minimum shared memory segement size. | |
| DFLT_SEG_SIZE=1048576 | |
| # This gets set if we have the numfmt command. | |
| HAVE_NUMFMT=0 | |
| # Record the running kernel release. | |
| UNAME_R=`uname -r 2>/dev/null` | |
| ###################################################################### | |
| # | |
| # Command-line option processing | |
| # | |
| ###################################################################### | |
| # | |
| # Display the help menu if no options were given. | |
| # | |
| if [ $# -eq 0 ]; then | |
| help | |
| exit 0 | |
| fi | |
| # | |
| # Check the command-line options. If set, these will override the | |
| # configuration file options. | |
| # | |
| while [ $# -ge 1 ]; do | |
| case "$1" in | |
| --append-log | --appendlog) | |
| APPEND_LOG=1 | |
| APPEND_OPT=1 | |
| ;; | |
| --bindir) | |
| RKHTMPVAR="$2" | |
| case "${RKHTMPVAR}" in | |
| "") | |
| ;; | |
| -*) | |
| RKHTMPVAR="" | |
| ;; | |
| *) | |
| shift | |
| BINPATHS="${BINPATHS} ${RKHTMPVAR}" | |
| BINDIR_OPT=1 | |
| ;; | |
| esac | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| echo "No command directories specified with '--bindir' option." | |
| exit 1 | |
| fi | |
| ;; | |
| -c | --check | --checkall | --check-all) | |
| CHECK=1 | |
| ;; | |
| -C | --config-check | --configcheck | --check-config | --checkconfig) | |
| CONFIG_CHECK=1 | |
| ;; | |
| --configfile) | |
| CONFIGFILE="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| CONFIGFILE="$1" | |
| ;; | |
| esac | |
| if [ -z "${CONFIGFILE}" ]; then | |
| echo "No configuration file specified with '--configfile' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --cronjob) | |
| CHECK=1 | |
| CRONJOB=1 | |
| COLORS=0 | |
| SKIP_KEY_PRESS=1 | |
| ;; | |
| --cs2 | --colorset2 | --color-set2) | |
| CLRSET2=1 | |
| ;; | |
| --dbdir) | |
| DB_PATH="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| DB_PATH="$1" | |
| ;; | |
| esac | |
| if [ -z "${DB_PATH}" ]; then | |
| echo "No database directory specified with '--dbdir' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --debug) | |
| SKIP_KEY_PRESS=1 | |
| ;; | |
| --display-logfile | --displaylogfile | --display-log | --displaylog | --showlog) | |
| CATLOGFILE=1 | |
| ;; | |
| --disable) | |
| RKHTMPVAR="$2" | |
| case "${RKHTMPVAR}" in | |
| "") | |
| ;; | |
| -*) | |
| RKHTMPVAR="" | |
| ;; | |
| *) | |
| shift | |
| CHECK=1 | |
| ENDIS_OPT=1 | |
| CL_DISABLE_TESTS="${CL_DISABLE_TESTS} ${RKHTMPVAR}" | |
| ;; | |
| esac | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| echo "No tests specified with '--disable' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --enable) | |
| RKHTMPVAR="$2" | |
| case "${RKHTMPVAR}" in | |
| "") | |
| ;; | |
| -*) | |
| RKHTMPVAR="" | |
| ;; | |
| *) | |
| shift | |
| CHECK=1 | |
| ENDIS_OPT=1 | |
| ENABLE_OPT=1 | |
| CL_ENABLE_TESTS="${CL_ENABLE_TESTS} ${RKHTMPVAR}" | |
| ;; | |
| esac | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| echo "No tests specified with '--enable' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --hash) | |
| HASH_FUNC="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| HASH_FUNC="$1" | |
| HASH_OPT=1 | |
| ;; | |
| esac | |
| if [ -z "${HASH_FUNC}" ]; then | |
| echo "No hash function specified with '--hash' option." | |
| exit 1 | |
| fi | |
| ;; | |
| -h | --help) | |
| help | |
| exit 0 | |
| ;; | |
| -l | --log | --logfile | --createlogfile | --createlog | --create-log | --create-logfile) | |
| RKHLOGFILE="${DFLT_LOGFILE}" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| RKHLOGFILE="$1" | |
| ;; | |
| esac | |
| ;; | |
| --lang | --language) | |
| LANGUAGE="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| LANGUAGE="$1" | |
| ;; | |
| esac | |
| if [ -z "${LANGUAGE}" ]; then | |
| echo "No language specified with '$1' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --list) | |
| case "$2" in | |
| test | tests | check | checks) | |
| shift | |
| LIST_OPT="${LIST_OPT} tests " | |
| ;; | |
| lang | langs | language | languages) | |
| shift | |
| LIST_OPT="${LIST_OPT} languages " | |
| ;; | |
| rootkit | rootkits) | |
| shift | |
| LIST_OPT="${LIST_OPT} rootkits " | |
| ;; | |
| perl | modules) | |
| shift | |
| LIST_OPT="${LIST_OPT} perl " | |
| ;; | |
| propfiles) | |
| shift | |
| LIST_OPT="${LIST_OPT} propfiles " | |
| ;; | |
| "") | |
| LIST_OPT="${LIST_OPT} tests languages rootkits perl " | |
| ;; | |
| *) | |
| echo "Invalid '--list' option specified: $2" | |
| exit 1 | |
| ;; | |
| esac | |
| ;; | |
| --noappend-log | --no-append-log | --noappendlog) | |
| APPEND_LOG=0 | |
| APPEND_OPT=1 | |
| ;; | |
| --nocf) | |
| USECF=0 | |
| ;; | |
| --nocolors | --no-colors | --nocolor | --no-color) | |
| COLORS=0 | |
| ;; | |
| --nolog | --no-log) | |
| RKHLOGFILE="/dev/null" | |
| ;; | |
| --nomow | --no-mow | --no-mailonwarning | --no-mail-on-warning) | |
| NOMOW=1 | |
| ;; | |
| --novl | --noverboselogging | --no-verbose-logging) | |
| VERBOSE_LOGGING=0 | |
| ;; | |
| --ns | --nosummary | --no-summary) | |
| SHOW_SUMMARY=0 | |
| SHOW_SUMMARY_OPT=1 | |
| ;; | |
| --pkgmgr) | |
| PKGMGR="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| PKGMGR="$1" | |
| ;; | |
| esac | |
| if [ -z "${PKGMGR}" ]; then | |
| echo "No package manager specified with '--pkgmgr' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --propupd | --prop-update | --propupdate | --properties-update | --hashupd) | |
| PROP_UPDATE=1 | |
| PROPUPD_OPT="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| PROPUPD_OPT="$1" | |
| ;; | |
| esac | |
| ;; | |
| -q | --quiet) | |
| QUIET=1 | |
| ;; | |
| --rwo | --swo | --report-warnings-only | --show-warnings-only) | |
| QUIET=1 | |
| SHOWWARNINGSONLY=1 | |
| ;; | |
| -r | --rootdir) | |
| echo "The '$1' option is now deprecated." | |
| shift | |
| ;; | |
| -sk | --sk | --skip-keypress | --skipkeypress) | |
| SKIP_KEY_PRESS=1 | |
| ;; | |
| --summary) | |
| SHOW_SUMMARY=1 | |
| SHOW_SUMMARY_OPT=1 | |
| ;; | |
| --syslog) | |
| USE_SYSLOG="${SYSLOG_DFLT_PRIO}" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| USE_SYSLOG="$1" | |
| ;; | |
| esac | |
| ;; | |
| --tmpdir) | |
| RKHTMPDIR="" | |
| case "$2" in | |
| "") | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| shift | |
| RKHTMPDIR="$1" | |
| ;; | |
| esac | |
| if [ -z "${RKHTMPDIR}" ]; then | |
| echo "No temporary directory specified with '--tmpdir' option." | |
| exit 1 | |
| fi | |
| ;; | |
| --unlock) | |
| UNLOCK=1 | |
| ;; | |
| --update) | |
| UPDATE=1 | |
| ;; | |
| --vl | --verboselogging | --verbose-logging) | |
| VERBOSE_LOGGING=1 | |
| ;; | |
| -V | --version) | |
| echo "${PROGRAM_NAME} ${PROGRAM_version}" | |
| echo "${PROGRAM_blurb}" | |
| exit 0 | |
| ;; | |
| --versioncheck | --version-check) | |
| VERSIONCHECK=1 | |
| ;; | |
| -x | --autox) | |
| AUTO_X_OPT=1 | |
| AUTO_X_DTCT=1 | |
| ;; | |
| -X | --no-autox) | |
| AUTO_X_OPT=1 | |
| AUTO_X_DTCT=0 | |
| ;; | |
| *) | |
| echo "Invalid option specified: $1" | |
| exit 1 | |
| ;; | |
| esac | |
| shift | |
| done | |
| # | |
| # We check that we are root. If we are not, then only the | |
| # help and version command-line options are valid. | |
| # | |
| if [ $SUNOS -eq 1 ]; then | |
| test -x /usr/xpg4/bin/id && ID_CMD="/usr/xpg4/bin/id" | |
| # | |
| # Unfortunately we need the AWK_CMD set this early on so | |
| # that the option processing works. As such this is a bit | |
| # of a hack. AWK_CMD will be set properly later on. | |
| # | |
| RKHTMPVAR=`which gawk 2>/dev/null | grep -v ' '` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| AWK_CMD="${RKHTMPVAR}" | |
| else | |
| RKHTMPVAR=`which nawk 2>/dev/null | grep -v ' '` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| AWK_CMD="${RKHTMPVAR}" | |
| elif [ -x "/usr/xpg4/bin/awk" ]; then | |
| AWK_CMD="/usr/xpg4/bin/awk" | |
| fi | |
| fi | |
| fi | |
| RKHTMPVAR=`${ID_CMD} -u 2>/dev/null` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR=`whoami 2>/dev/null` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR=`who am i 2>/dev/null | cut -d' ' -f1` | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| RKHTMPVAR=`who -m 2>/dev/null | cut -d' ' -f1` | |
| fi | |
| fi | |
| fi | |
| if [ -z "${RKHTMPVAR}" ]; then | |
| echo "Unable to determine if you are root." | |
| exit 1 | |
| elif [ "${RKHTMPVAR}" != "0" -a "${RKHTMPVAR}" != "root" ]; then | |
| echo "You must be the root user to run this program." | |
| exit 1 | |
| fi | |
| # | |
| # We need to see if we are to run a check before we get to the | |
| # configuration file processing code. Basically if either of the | |
| # '--enable' or '--disable' options are used, then we will do a | |
| # check. | |
| # | |
| if [ $ENDIS_OPT -eq 1 ]; then | |
| CL_ENABLE_TESTS=`echo ${CL_ENABLE_TESTS} | tr -d '"' | tr -d "'" | tr ',' ' ' | tr '[:upper:]' '[:lower:]'` | |
| CL_DISABLE_TESTS=`echo ${CL_DISABLE_TESTS} | tr -d '"' | tr -d "'" | tr ',' ' ' | tr '[:upper:]' '[:lower:]'` | |
| CL_DISABLE_TESTS=`echo ${CL_DISABLE_TESTS}` | |
| # The '--nocf' option is only for disabled tests. | |
| test -z "${CL_DISABLE_TESTS}" && USECF=1 | |
| else | |
| USECF=1 | |
| fi | |
| # | |
| # See if only the '--update' option has been used. | |
| # | |
| test $UPDATE -eq 1 -a $CHECK -eq 0 -a $PROP_UPDATE -eq 0 -a $VERSIONCHECK -eq 0 && UPDATE_ONLY=1 | |
| # | |
| # Before going too much further we need to ensure that some basic | |
| # commands are present on the system. We cannot do this using | |
| # the BINDIR option because that requires processing the configuration | |
| # file, which in turn requires the commands we want to check on. As | |
| # such we use the default command directory list. We do not assign | |
| # these commands to variables, but will do for other commands which we | |
| # look for later on. | |
| # | |
| check_required_commands 1 | |
| ###################################################################### | |
| # | |
| # Configuration file processing | |
| # | |
| ###################################################################### | |
| # | |
| # Now we check for the configuration file. We then see if there is a | |
| # local configuration file, and/or a local directory, present in the | |
| # same directory, and finally check the various options within them. | |
| # | |
| # NOTE: Do not change the format of the following 'if' statement. | |
| # The installer script will modify it directly during installation. | |
| # | |
| if [ -z "${CONFIGFILE}" ]; then | |
| if [ -f /etc/rkhunter.conf ]; then | |
| CONFIGFILE="/etc/rkhunter.conf" | |
| else | |
| CONFIGFILE="/usr/local/etc/rkhunter.conf" | |
| fi | |
| fi | |
| if [ ! -f "${CONFIGFILE}" ]; then | |
| echo "Unable to find configuration file: ${CONFIGFILE}" | |
| exit 1 | |
| elif [ ! -r "${CONFIGFILE}" ]; then | |
| echo "Configuration file is not readable: ${CONFIGFILE}" | |
| exit 1 | |
| elif [ ! -s "${CONFIGFILE}" ]; then | |
| echo "Configuration file is empty: ${CONFIGFILE}" | |
| exit 1 | |
| fi | |
| RKHTMPVAR=`echo "${CONFIGFILE}" | sed -e 's:/[^/]*$::'` | |
| test -f "${RKHTMPVAR}/rkhunter.conf.local" -a ! -h "${RKHTMPVAR}/rkhunter.conf.local" -a -r "${RKHTMPVAR}/rkhunter.conf.local" && LOCALCONFIGFILE="${RKHTMPVAR}/rkhunter.conf.local" | |
| if [ -d "${RKHTMPVAR}/rkhunter.d" ]; then | |
| LOCALCONFIGDIR="${RKHTMPVAR}/rkhunter.d" | |
| for FNAME in ${LOCALCONFIGDIR}/*.conf; do | |
| test ! -f "${FNAME}" -o -h "${FNAME}" -o ! -r "${FNAME}" && continue | |
| LOCALCONFDIRCOUNT=`expr ${LOCALCONFDIRCOUNT} + 1` | |
| LOCALCONFDIRFILES="${LOCALCONFDIRFILES} ${FNAME}" | |
| done | |
| fi | |
| get_configfile_options | |
| # | |
| # If we are doing a configuration file | |
| # check, then this is as far as we go. | |
| # | |
| if [ $CONFIG_CHECK -eq 1 ]; then | |
| do_config_file_check | |
| exit $RET_CODE | |
| fi | |
| ###################################################################### | |
| # | |
| # Option processing | |
| # | |
| ###################################################################### | |
| # | |
| # Next we check some of the options to make sure we can proceed. We | |
| # also set up some final variables based on the combination of options | |
| # we have been given. | |
| # | |
| # | |
| # First we process the '--list' option if it has been given. | |
| # | |
| if [ -n "${LIST_OPT}" ]; then | |
| for RKHTMPVAR in ${LIST_OPT}; do | |
| case "${RKHTMPVAR}" in | |
| tests) | |
| display_tests | |
| ;; | |
| languages) | |
| display_languages | |
| ;; | |
| perl) | |
| display_perl_modules | |
| ;; | |
| propfiles) | |
| display_propfiles | |
| ;; | |
| *) | |
| display_rootkits | |
| ;; | |
| esac | |
| done | |
| exit 0 | |
| fi | |
| # | |
| # Next we must see if we are doing an update only, and if there were | |
| # some language file problems. If so, then we must not log or display | |
| # anything. | |
| # | |
| if [ $RKHLANGUPDT -eq 1 ]; then | |
| QUIET=1 | |
| COLORS=0 | |
| RKHLOGFILE="/dev/null" | |
| fi | |
| # | |
| # If the logfile has been disabled, then we cannot let the | |
| # program run when certain options are used. If we did, the user | |
| # would see no output and might assume that all was well. | |
| # | |
| if [ "${RKHLOGFILE}" = "/dev/null" ]; then | |
| NOLOG=1 | |
| VERBOSE_LOGGING=0 | |
| COPY_LOG_ON_ERROR=0 | |
| if [ $SHOWWARNINGSONLY -eq 1 ]; then | |
| echo "The logfile has been disabled - unable to report warnings." | |
| exit 1 | |
| elif [ $CATLOGFILE -eq 1 ]; then | |
| echo "The logfile has been disabled - unable to display the log file." | |
| exit 1 | |
| fi | |
| fi | |
| # | |
| # Set up the colors to be used. | |
| # | |
| if [ $COLORS -eq 1 ]; then | |
| NORMAL="[0;39m" # Foreground colour to default | |
| if [ $CLRSET2 -eq 0 ]; then | |
| RED="[1;31m" # Bright red | |
| GREEN="[1;32m" # Bright green | |
| YELLOW="[1;33m" # Bright yellow | |
| WHITE="[1;37m" # White | |
| else | |
| RED="[1;31m" # Bright red | |
| GREEN="[0;32m" # Green | |
| YELLOW="[0;35m" # Purple | |
| WHITE="[0;30m" # Black | |
| fi | |
| fi | |
| if [ $CHECK -eq 1 ]; then | |
| # | |
| # Check if we have a kernel symbols file. | |
| # | |
| if [ -f "/proc/ksyms" ]; then | |
| KSYMS_FILE="/proc/ksyms" | |
| elif [ -f "/proc/kallsyms" ]; then | |
| KSYMS_FILE="/proc/kallsyms" | |
| elif [ -f "/boot/System.map-${UNAME_R}" ]; then | |
| KSYMS_FILE="/boot/System.map-${UNAME_R}" | |
| fi | |
| fi | |
| if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 ]; then | |
| if [ -e "${RKHDAT_FILE}" ]; then | |
| if [ -h "${RKHDAT_FILE}" ]; then | |
| echo "The rkhunter.dat file is a symbolic link: ${RKHDAT_FILE}" | |
| echo "This is a security problem. The link points to another file, and that file may be modified by rkhunter." | |
| exit 1 | |
| elif [ ! -f "${RKHDAT_FILE}" ]; then | |
| echo "The rkhunter.dat file is not a file: ${RKHDAT_FILE}" | |
| exit 1 | |
| fi | |
| fi | |
| if [ -e "${RKH_FILEPROP_LIST}" ]; then | |
| if [ -h "${RKH_FILEPROP_LIST}" ]; then | |
| echo "The rkhunter_prop_list.dat file is a symbolic link: ${RKH_FILEPROP_LIST}" | |
| echo "This is a security problem. The link points to another file, and that file may be modified by rkhunter." | |
| exit 1 | |
| elif [ ! -f "${RKH_FILEPROP_LIST}" ]; then | |
| echo "The rkhunter_prop_list.dat file is not a file: ${RKH_FILEPROP_LIST}" | |
| exit 1 | |
| fi | |
| fi | |
| # | |
| # Check if the file properties option has been set. If so, then | |
| # check that the files and directories are valid. Once that has | |
| # been done, we can then set up the file properties check directories | |
| # and file names. | |
| # | |
| if [ -n "${PROPUPD_OPT}" ]; then | |
| if [ ! -f "${RKHDAT_FILE}" ]; then | |
| echo "The file properties file does not exist: ${RKHDAT_FILE}" | |
| exit 1 | |
| fi | |
| # | |
| # We need the current 'rkhunter.dat' file format. | |
| # | |
| FMTVERSION=`grep '^FormatVersion:' "${RKHDAT_FILE}" | cut -d: -f2` | |
| test -z "${FMTVERSION}" && FMTVERSION=0 | |
| LEAVE=0 | |
| RKHTMPVAR="" | |
| PROPUPD_OPT=`echo "${PROPUPD_OPT}" | tr ',' "\n" | sed -e '/^$/d'` | |
| test "${PROPUPD_OPT}" = "/" && PROPUPD_OPT="" | |
| IFS=$IFSNL | |
| for FNAME in ${PROPUPD_OPT}; do | |
| if [ -n "`echo \"${FNAME}\" | grep '^[^/].*/'`" ]; then | |
| # Filename is relative | |
| LEAVE=1 | |
| echo "Relative file or directory name specified: ${FNAME}" | |
| elif [ -n "`echo \"${FNAME}\" | grep '^/'`" ]; then | |
| # Filename is absolute | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHTMPVAR2=`grep "^File:${FNAMEGREP}:" "${RKHDAT_FILE}" 2>/dev/null | cut -d: -f2` | |
| else | |
| COLON_COUNT=`echo "${FNAME}" | tr -c -d ':' | wc -c | tr -d ' '` | |
| RKHTMPVAR2=`grep "^File:${COLON_COUNT}:${FNAMEGREP}:" "${RKHDAT_FILE}" 2>/dev/null` | |
| test -n "${RKHTMPVAR2}" && RKHTMPVAR2="${FNAME}" | |
| fi | |
| if [ -z "${RKHTMPVAR2}" ]; then | |
| if [ -d "${FNAME}" ]; then | |
| # Filename is a directory | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHTMPVAR2=`grep "^File:${FNAMEGREP}/[^:]*:" "${RKHDAT_FILE}" 2>/dev/null | cut -d: -f2` | |
| else | |
| PATHS="" | |
| IFS=$IFSNL | |
| for RKHLINE in `grep "^File:[0-9]*:${FNAMEGREP}/" "${RKHDAT_FILE}"`; do | |
| COLON_COUNT=`echo "${RKHLINE}" | cut -d: -f2` | |
| COLON_COUNT=`expr 3 + $COLON_COUNT` | |
| PATHNAME=`echo "${RKHLINE}" | cut -d: -f3-$COLON_COUNT` | |
| PATHS="${PATHS} | |
| ${PATHNAME}" | |
| done | |
| IFS=$RKHIFS | |
| RKHTMPVAR2=`echo "${PATHS}" | sed -e '/^$/d'` | |
| fi | |
| if [ -n "${RKHTMPVAR2}" ]; then | |
| RKHTMPVAR="${RKHTMPVAR} | |
| ${RKHTMPVAR2}" | |
| else | |
| LEAVE=1 | |
| echo "Directory is not in the \"rkhunter.dat\" file: ${FNAME}" | |
| fi | |
| else | |
| LEAVE=1 | |
| echo "Filename is not in the \"rkhunter.dat\" file: ${FNAME}" | |
| fi | |
| else | |
| RKHTMPVAR="${RKHTMPVAR} | |
| ${RKHTMPVAR2}" | |
| fi | |
| else | |
| # | |
| # Filename could be a package name. | |
| # The package names are currently in field 11 in the 'rkhunter.dat' file. | |
| # | |
| FNAMEGREP=`echo "${FNAME}" | sed -e 's/\([.$*?\\]\)/\\\\\1/g; s/\[/\\\\[/g; s/\]/\\\\]/g'` | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHTMPVAR2=`grep "^File:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:${FNAMEGREP}:" "${RKHDAT_FILE}" 2>/dev/null | cut -d: -f2` | |
| else | |
| PATHS="" | |
| IFS=$IFSNL | |
| for RKHLINE in `grep "^File:[0-9]*:.*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:${FNAMEGREP}:" "${RKHDAT_FILE}"`; do | |
| COLON_COUNT=`echo "${RKHLINE}" | cut -d: -f2` | |
| COLON_COUNT=`expr 3 + $COLON_COUNT` | |
| PATHNAME=`echo "${RKHLINE}" | cut -d: -f3-$COLON_COUNT` | |
| PATHS="${PATHS} | |
| ${PATHNAME}" | |
| done | |
| IFS=$RKHIFS | |
| RKHTMPVAR2=`echo "${PATHS}" | sed -e '/^$/d'` | |
| fi | |
| if [ -z "${RKHTMPVAR2}" ]; then | |
| # Filename is just a plain filename | |
| if [ $FMTVERSION -eq 0 ]; then | |
| RKHTMPVAR2=`grep "^File:[^:]*/${FNAMEGREP}:" "${RKHDAT_FILE}" 2>/dev/null | cut -d: -f2` | |
| else | |
| PATHS="" | |
| IFS=$IFSNL | |
| for RKHLINE in `grep "^File:[0-9]*:.*/${FNAMEGREP}:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:" "${RKHDAT_FILE}"`; do | |
| COLON_COUNT=`echo "${RKHLINE}" | cut -d: -f2` | |
| COLON_COUNT=`expr 3 + $COLON_COUNT` | |
| PATHNAME=`echo "${RKHLINE}" | cut -d: -f3-$COLON_COUNT` | |
| PATHS="${PATHS} | |
| ${PATHNAME}" | |
| done | |
| IFS=$RKHIFS | |
| RKHTMPVAR2=`echo "${PATHS}" | sed -e '/^$/d'` | |
| fi | |
| if [ -n "${RKHTMPVAR2}" ]; then | |
| RKHTMPVAR="${RKHTMPVAR} | |
| ${RKHTMPVAR2}" | |
| else | |
| LEAVE=1 | |
| echo "File or package name is not in the \"rkhunter.dat\" file: ${FNAME}" | |
| fi | |
| else | |
| RKHTMPVAR="${RKHTMPVAR} | |
| ${RKHTMPVAR2}" | |
| fi | |
| fi | |
| done | |
| IFS=$RKHIFS | |
| if [ $LEAVE -eq 0 ]; then | |
| PROPUPD_OPT=`echo "${RKHTMPVAR}" | sed -e '/^$/d'` | |
| else | |
| exit 1 | |
| fi | |
| fi | |
| if `check_test properties` || test $PROP_UPDATE -eq 1; then | |
| set_file_prop_dirs_files | |
| fi | |
| # | |
| # We need to record the previously used | |
| # hash function and package manager. | |
| # | |
| get_old_prop_attrs "${RKHDAT_FILE}" | |
| fi | |
| if [ $PROP_UPDATE -eq 1 -a $PRELINKED -eq 1 -a -z "${PKGMGR}" -a "${HASH_FUNC}" != "NONE" ]; then | |
| # | |
| # For a hash update on a prelinked system, we must have | |
| # a valid hash function to use. | |
| # | |
| if [ -z "${PRELINK_HASH}" ]; then | |
| if [ -z "`echo \"${HASH_FUNC}\" | grep -E '(/filehashsha\.pl Digest::MD5|/filehashsha\.pl .* 1$|shasum -a 1$)'`" ]; then | |
| RKHTMPVAR=`echo "${HASH_FUNC}" | cut -d' ' -f1` | |
| if [ -z "`echo ${RKHTMPVAR} | grep -E -i 'sha1|md5'`" ]; then | |
| if [ $HASH_OPT -eq 1 ]; then | |
| echo "This system uses prelinking, but the '--hash' option (${HASH_FUNC}) does not look like SHA1 or MD5." | |
| else | |
| echo "This system uses prelinking, but the hash function (${HASH_FUNC}) does not look like SHA1 or MD5." | |
| fi | |
| exit 1 | |
| fi | |
| fi | |
| fi | |
| fi | |
| # | |
| # For the update and versioncheck options, we need to make sure | |
| # we have a command capable of downloading files from the web. | |
| # The first command found is used, unless it has been set in | |
| # the configuration file. | |
| # | |
| if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 ]; then | |
| if [ -z "${RKHWEBCMD}" ]; then | |
| FOUND=0 | |
| for CMD in ${WEBCMDLIST}; do | |
| # | |
| # Ignore perl commands if perl is not present, or if | |
| # certain modules are not present. | |
| # | |
| if [ "${CMD}" = "GET" ]; then | |
| test -z "${PERL_CMD}" && continue | |
| RKHTMPVAR=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" LWP URI HTTP::Status HTTP::Date Getopt::Long 2>&1 | grep 'NOT'` | |
| test -n "${RKHTMPVAR}" && continue | |
| elif [ "${CMD}" = "bget" ]; then | |
| test -z "${PERL_CMD}" && continue | |
| RKHTMPVAR=`${PERL_CMD} "${SCRIPT_PATH}/check_modules.pl" Socket Carp 2>&1 | grep 'NOT'` | |
| test -n "${RKHTMPVAR}" && continue | |
| fi | |
| RKHTMPVAR=`find_cmd ${CMD}` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| FOUND=1 | |
| RKHWEBCMD="${RKHTMPVAR}" | |
| RKHWEBCMD_BASE="${CMD}" | |
| break | |
| fi | |
| done | |
| if [ $FOUND -eq 0 ]; then | |
| echo "The '--update' and '--versioncheck' options require a command able to" | |
| echo "download files from the web. No such command can be found on the system." | |
| echo "Examples of commands that could be used are: ${WEBCMDLIST}" | |
| exit 1 | |
| fi | |
| fi | |
| fi | |
| # | |
| # If no option is given for the program to action, then say so and exit. | |
| # | |
| if [ $CHECK -eq 0 -a $VERSIONCHECK -eq 0 -a $UPDATE -eq 0 -a $PROP_UPDATE -eq 0 -a $UNLOCK -eq 0 ]; then | |
| echo "You must enter an option for the program to perform." | |
| echo "Type in 'rkhunter --help' to see the available options," | |
| echo "or read the rkhunter man page." | |
| exit 1 | |
| fi | |
| # | |
| # Handle any locking straight away. | |
| # | |
| if [ $UNLOCK -eq 1 ]; then | |
| rm -f "${LOCKDIR}/rkhunter.LCK" >/dev/null 2>&1 | |
| # If we are just unlocking the lock file, then exit. | |
| test $CHECK -eq 0 -a $VERSIONCHECK -eq 0 -a $UPDATE -eq 0 -a $PROP_UPDATE -eq 0 && exit 0 | |
| fi | |
| # | |
| # Before writing anything to the screen or log file, we need to | |
| # set some variables. | |
| # | |
| # First we set whether we should be displaying anything on the | |
| # screen or not. | |
| # | |
| test $CRONJOB -eq 1 -o $QUIET -eq 1 && NOTTY=1 | |
| # | |
| # Next we get the message types and results from the language file, | |
| # and set them to variables. We have to look in the English file since | |
| # that is the definitive one. We then look for the corresponding keyword | |
| # in the actual language file. This allows the language files to work | |
| # even if we add or remove any of the TYPE or RESULT keywords. | |
| # | |
| IFS=$IFSNL | |
| for LINE in `grep -E '^MSG_(TYPE|RESULT)_' "${DB_PATH}/i18n/en" 2>/dev/null`; do | |
| TYPE=`echo "${LINE}" | cut -d: -f1` | |
| if [ "${LANGUAGE}" != "en" ]; then | |
| RKHTMPVAR=`grep ${GREP_OPT} "^${TYPE}:" "${DB_PATH}/i18n/${LANGUAGE}" 2>/dev/null` | |
| test -n "${RKHTMPVAR}" && LINE=`echo "${RKHTMPVAR}" | sed -e 's/\`/\\\\\`/g'` | |
| fi | |
| RKHTMPVAR=`echo "${LINE}" | cut -d: -f2-` | |
| eval $TYPE=\"${RKHTMPVAR}\" | |
| done | |
| IFS=$RKHIFS | |
| # | |
| # Before we touch the log file we must see if locking is being used. | |
| # | |
| if [ $USE_LOCKING -eq 1 ]; then | |
| get_lock | |
| fi | |
| # | |
| # Sort out the logfile before we write to it. | |
| # | |
| if [ $NOLOG -eq 0 ]; then | |
| if [ $APPEND_LOG -eq 0 ]; then | |
| if [ -f "${RKHLOGFILE}" ]; then | |
| cp -f -p "${RKHLOGFILE}" "${RKHLOGFILE}.old" >/dev/null 2>&1 | |
| # Overwrite the log file with a null string. | |
| if [ "${ECHON}" = "c" ]; then | |
| echo $ECHOOPT "\c" >"${RKHLOGFILE}" | |
| else | |
| echo $ECHON $ECHOOPT "" >"${RKHLOGFILE}" | |
| fi | |
| else | |
| # Create a new log file. | |
| touch "${RKHLOGFILE}" >/dev/null 2>&1 | |
| chmod 600 "${RKHLOGFILE}" >/dev/null 2>&1 | |
| fi | |
| else | |
| if [ ! -f "${RKHLOGFILE}" ]; then | |
| # Create a new log file. | |
| touch "${RKHLOGFILE}" >/dev/null 2>&1 | |
| chmod 600 "${RKHLOGFILE}" >/dev/null 2>&1 | |
| fi | |
| echo "" >>"${RKHLOGFILE}" | |
| echo "" >>"${RKHLOGFILE}" | |
| fi | |
| fi | |
| # | |
| # Record the hostname. This will be used at several points | |
| # throughout the program. A specific test will specify if | |
| # a hostname has been found or not, so we don't need to | |
| # do anything special here. | |
| # | |
| HOST_NAME=`hostname 2>/dev/null` | |
| test -z "${HOST_NAME}" && HOST_NAME=`uname -n 2>/dev/null` | |
| test -z "${HOST_NAME}" && HOST_NAME="${HOSTNAME}" | |
| HOST_NAME=`echo ${HOST_NAME} | cut -d. -f1` | |
| ###################################################################### | |
| # | |
| # Initial logging | |
| # | |
| ###################################################################### | |
| # | |
| # Write out various information messages to the logfile. The first | |
| # set of messages can be skipped if no logfile is to be created. | |
| # | |
| display --to SCREEN --type PLAIN VERSIONLINE "${PROGRAM_NAME}" "${PROGRAM_version}" | |
| if [ $NOLOG -eq 0 ]; then | |
| if [ -n "${HOST_NAME}" ]; then | |
| display --to LOG --type PLAIN VERSIONLINE2 "${PROGRAM_NAME}" "${PROGRAM_version}" "${HOST_NAME}" | |
| else | |
| display --to LOG --type PLAIN VERSIONLINE3 "${PROGRAM_NAME}" "${PROGRAM_version}" | |
| fi | |
| display --to LOG --type INFO --nl RKH_STARTDATE "`date`" | |
| display --to LOG --type PLAIN --nl CONFIG_CHECK_START | |
| display --to LOG --type INFO OPSYS "${OPERATING_SYSTEM}" | |
| if [ -s "${RKHDAT_FILE}" ]; then | |
| RKHTMPVAR=`grep '^OS:' "${RKHDAT_FILE}" 2>/dev/null | sed -e 's/^OS://'` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| display --to LOG --type INFO PROPUPD_OSNAME_FOUND "${RKHTMPVAR}" | |
| else | |
| display --to LOG --type INFO UNAME "`uname -a`" | |
| fi | |
| else | |
| display --to LOG --type INFO UNAME "`uname -a`" | |
| fi | |
| display --to LOG --type INFO CONFIG_CMDLINE "${CMD_LINE}" | |
| test $DEBUG_OPT -eq 1 && display --to LOG --type INFO CONFIG_DEBUGFILE "${RKHDEBUGFILE}" | |
| display --to LOG --type INFO CONFIG_ENVSHELL "${SHELL}" "${MYSHELL}" | |
| display --to LOG --type INFO CONFIG_CONFIGFILE "${CONFIGFILE}" | |
| test -n "${LOCALCONFIGFILE}" && display --to LOG --type INFO CONFIG_LOCALCONFIGFILE "${LOCALCONFIGFILE}" | |
| if [ -n "${LOCALCONFIGDIR}" ]; then | |
| test $LOCALCONFDIRCOUNT -eq 1 && RKHTMPVAR="" || RKHTMPVAR="s" | |
| display --to LOG --type INFO CONFIG_LOCALCONFIGDIR "${LOCALCONFIGDIR}" $LOCALCONFDIRCOUNT "${RKHTMPVAR}" | |
| fi | |
| display --to LOG --type INFO CONFIG_INSTALLDIR "${RKHINSTALLDIR}" | |
| display --to LOG --type INFO CONFIG_LANGUAGE "${LANGUAGE}" | |
| display --to LOG --type INFO CONFIG_DBDIR "${DB_PATH}" | |
| display --to LOG --type INFO CONFIG_SCRIPTDIR "${SCRIPT_PATH}" | |
| display --to LOG --type INFO CONFIG_BINDIR "${BINPATHS}" | |
| display --to LOG --type INFO CONFIG_TMPDIR "${RKHTMPDIR}" | |
| if [ $CHECK -eq 1 ]; then | |
| if [ $NOMOW -eq 1 ]; then | |
| display --to LOG --type INFO CONFIG_MOW_DISABLED | |
| elif [ -z "${MAILONWARNING}" ]; then | |
| display --to LOG --type INFO CONFIG_NO_MAIL_ON_WARN | |
| else | |
| display --to LOG --type INFO CONFIG_MAIL_ON_WARN "${MAILONWARNING}" "${MAIL_CMD}" | |
| fi | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| test $AUTO_X_DTCT -eq 1 && display --to LOG --type INFO CONFIG_X_AUTO | |
| test $CLRSET2 -eq 1 && display --to LOG --type INFO CONFIG_CLRSET2 | |
| for CMD in ${CMDLIST}; do | |
| RKHTMPVAR=`echo ${CMD} | tr '[:lower:]' '[:upper:]'` | |
| RKHTMPVAR=`eval echo "\\$${RKHTMPVAR}_CMD"` | |
| if [ -n "${RKHTMPVAR}" ]; then | |
| display --to LOG --type INFO FOUND_CMD "${CMD}" "${RKHTMPVAR}" | |
| elif [ -n "`echo \"${DISABLED_CMDS}\" | grep \" ${CMD} \"`" ]; then | |
| display --to LOG --type INFO DISABLED_CMD "${CMD}" | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD "${CMD}" | |
| fi | |
| done | |
| test -n "${RKHWEBCMD}" && display --to LOG --type INFO FOUND_CMD "${RKHWEBCMD_BASE}" "${RKHWEBCMD}" | |
| fi | |
| fi | |
| if [ $PROP_UPDATE -eq 1 -o $HASH_CHECK_ENABLED -eq 1 ]; then | |
| if [ -z "${PKGMGR}" -a "${HASH_FUNC}" = "NONE" ]; then | |
| HASH_CHECK_ENABLED=0 | |
| DISABLE_TESTS="${DISABLE_TESTS} hashes" | |
| display --to LOG --type INFO HASH_FUNC_DISABLED | |
| fi | |
| if [ $PRELINKED -eq 1 ]; then | |
| display --to LOG --type INFO SYS_PRELINK | |
| display --to LOG --type INFO FOUND_CMD 'prelink' "${PRELINK_CMD}" | |
| if [ -n "${SESTATUS_CMD}" ]; then | |
| display --to LOG --type INFO FOUND_CMD 'sestatus' "${SESTATUS_CMD}" | |
| if [ $SELINUX_ENABLED -eq 1 ]; then | |
| display --to LOG --type INFO SYS_SELINUX | |
| if [ $USE_RUNCON -eq 1 ]; then | |
| display --to LOG --type INFO FOUND_CMD 'runcon' "${RUNCON_CMD}" | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'runcon' | |
| fi | |
| else | |
| display --to LOG --type INFO SYS_NO_SELINUX | |
| fi | |
| else | |
| display --to LOG --type INFO NOT_FOUND_CMD 'sestatus' | |
| fi | |
| if [ "${HASH_FUNC}" = "NONE" ]; then | |
| if [ -n "${PKGMGR}" ]; then | |
| display --to LOG --type INFO HASH_FUNC_NONE_PKGMGR | |
| else | |
| display --to LOG --type INFO HASH_FUNC_NONE | |
| fi | |
| elif [ -n "${PRELINK_HASH}" ]; then | |
| display --to LOG --type INFO HASH_FUNC_PRELINK "${PRELINK_HASH}" | |
| elif [ -z "`echo \"${HASH_FUNC}\" | grep -E -i 'sha1|md5'`" ]; then | |
| SKIP_HASH_MSG=1 | |
| else | |
| display --to LOG --type INFO HASH_FUNC "${HASH_FUNC}" | |
| fi | |
| else | |
| display --to LOG --type INFO SYS_NO_PRELINK | |
| if [ "${HASH_FUNC}" = "NONE" ]; then | |
| if [ -n "${PKGMGR}" ]; then | |
| display --to LOG --type INFO HASH_FUNC_NONE_PKGMGR | |
| else | |
| display --to LOG --type INFO HASH_FUNC_NONE | |
| fi | |
| elif [ -n "`echo \"${HASH_FUNC}\" | grep '/filehashsha\.pl '`" ]; then | |
| RKHTMPVAR=`echo "${HASH_FUNC}" | cut -d' ' -f3` | |
| if [ $SHA_SIZE -eq 0 ]; then | |
| display --to LOG --type INFO HASH_FUNC_PERL "${RKHTMPVAR}" | |
| else | |
| display --to LOG --type INFO HASH_FUNC_PERL_SHA "${RKHTMPVAR}" "SHA${SHA_SIZE}" | |
| fi | |
| else | |
| display --to LOG --type INFO HASH_FUNC "${HASH_FUNC}" | |
| fi | |
| fi | |
| if [ -s "${RKHDAT_FILE}" ]; then | |
| if [ "${OLD_HASH_FUNC}" = "Disabled" ]; then | |
| display --to LOG --type INFO HASH_FUNC_OLD_DISABLED | |
| else | |
| display --to LOG --type INFO HASH_FUNC_OLD "${OLD_HASH_FUNC}" | |
| fi | |
| if [ -z "${OLD_PKGMGR}" ]; then | |
| display --to LOG --type INFO HASH_PKGMGR_OLD_UNSET | |
| else | |
| display --to LOG --type INFO HASH_PKGMGR_OLD "${OLD_PKGMGR}" | |
| fi | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO HASH_FIELD_INDEX "$HASH_FLD_IDX" | |
| fi | |
| if [ $PROP_UPDATE -eq 1 ]; then | |
| if ! `check_test hashes` && test $ENDIS_OPT -eq 0; then | |
| display --to LOG --type INFO HASHUPD_DISABLED | |
| elif [ -z "${PKGMGR}" ]; then | |
| if [ $PRELINKED -eq 1 ]; then | |
| if [ -n "${PRELINK_HASH}" ]; then | |
| display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC_PRELINKED "${PRELINK_HASH}" | |
| else | |
| display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC "${HASH_FUNC}" | |
| fi | |
| else | |
| display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC "${HASH_FUNC}" | |
| fi | |
| else | |
| display --to LOG --type INFO HASHUPD_PKGMGR "${PKGMGR}" | |
| case "${PKGMGR}" in | |
| RPM) | |
| display --to LOG --type INFO FOUND_CMD 'rpm' "${RPM_CMD}" | |
| ;; | |
| DPKG) | |
| if [ -z "`echo \"${DPKG_CMD}\" | grep '/dpkg$'`" ]; then | |
| display --to LOG --type INFO FOUND_CMD 'dpkg-query' "${DPKG_CMD}" | |
| else | |
| display --to LOG --type INFO FOUND_CMD 'dpkg' "${DPKG_CMD}" | |
| fi | |
| ;; | |
| BSD) | |
| display --to LOG --type INFO FOUND_CMD 'pkg_info' "${PKG_CMD}" | |
| ;; | |
| BSDNG) | |
| display --to LOG --type INFO FOUND_CMD 'pkg' "${PKG_CMD}" | |
| ;; | |
| SOLARIS) | |
| if [ $USE_SUNSUM -eq 1 ]; then | |
| display --to LOG --type INFO HASH_PKGMGR_SUM | |
| display --to LOG --type INFO FOUND_CMD 'sum' "${SUM_CMD}" | |
| fi | |
| ;; | |
| esac | |
| fi | |
| fi | |
| if [ $HASH_CHECK_ENABLED -eq 1 ]; then | |
| if [ -z "${PKGMGR}" ]; then | |
| if [ $PRELINKED -eq 1 ]; then | |
| if [ -n "${PRELINK_HASH}" ]; then | |
| display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC_PRELINKED "${PRELINK_HASH}" | |
| else | |
| display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC "${HASH_FUNC}" | |
| fi | |
| else | |
| display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC "${HASH_FUNC}" | |
| fi | |
| else | |
| display --to LOG --type INFO HASH_PKGMGR "${PKGMGR}" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| case "${PKGMGR}" in | |
| RPM) | |
| display --to LOG --type INFO FOUND_CMD 'rpm' "${RPM_CMD}" | |
| ;; | |
| DPKG) | |
| if [ -z "`echo \"${DPKG_CMD}\" | grep '/dpkg$'`" ]; then | |
| display --to LOG --type INFO FOUND_CMD 'dpkg-query' "${DPKG_CMD}" | |
| else | |
| display --to LOG --type INFO FOUND_CMD 'dpkg' "${DPKG_CMD}" | |
| fi | |
| display --to LOG --type INFO HASH_PKGMGR_MD5 "${PKGMGR_MD5_HASH}" | |
| ;; | |
| BSD) | |
| display --to LOG --type INFO FOUND_CMD 'pkg_info' "${PKG_CMD}" | |
| display --to LOG --type INFO HASH_PKGMGR_MD5 "${PKGMGR_MD5_HASH}" | |
| ;; | |
| BSDNG) | |
| display --to LOG --type INFO FOUND_CMD 'pkg' "${PKG_CMD}" | |
| display --to LOG --type INFO HASH_PKGMGR_SHA "${PKGMGR_SHA_HASH}" | |
| ;; | |
| SOLARIS) | |
| if [ $USE_SUNSUM -eq 1 ]; then | |
| display --to LOG --type INFO HASH_PKGMGR_SUM | |
| display --to LOG --type INFO FOUND_CMD 'sum' "${SUM_CMD}" | |
| fi | |
| ;; | |
| esac | |
| fi | |
| fi | |
| fi | |
| fi | |
| RKHTMPVAR=0 | |
| test $CHECK -eq 1 && `check_test attributes` && RKHTMPVAR=1 | |
| if [ $RKHTMPVAR -eq 1 ]; then | |
| if [ "${OLD_ATTRUPD}" = "Disabled" ]; then | |
| display --to LOG --type INFO ATTRUPD_OLD_DISABLED | |
| elif [ "${OLD_ATTRUPD}" = "Nostatcmd" ]; then | |
| display --to LOG --type INFO ATTRUPD_OLD_NOSTATCMD | |
| else | |
| display --to LOG --type INFO ATTRUPD_OLD_OK | |
| fi | |
| fi | |
| if [ $PROP_UPDATE -eq 1 ]; then | |
| if ! `check_test attributes` && test $ENDIS_OPT -eq 0; then | |
| display --to LOG --type INFO ATTRUPD_DISABLED | |
| elif [ -z "${STAT_CMD}" ]; then | |
| display --to LOG --type INFO ATTRUPD_NOSTATCMD | |
| else | |
| display --to LOG --type INFO ATTRUPD_OK | |
| fi | |
| fi | |
| if [ $CHECK -eq 1 ]; then | |
| display --to LOG --type INFO ENABLED_TESTS "${ENABLE_TESTS}" | |
| display --to LOG --type INFO DISABLED_TESTS "${DISABLE_TESTS}" | |
| fi | |
| if `check_test properties` || test $PROP_UPDATE -eq 1; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ -n "${USER_FILE_LIST}" ]; then | |
| display --to LOG --type INFO USER_FILE_LIST | |
| IFS=$IFSNL | |
| for FNAME in ${USER_FILE_LIST}; do | |
| display --to LOG --type PLAIN --log-indent 6 NAME "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 -a -n "${USER_SIMPLE_FILE_LIST}" ]; then | |
| display --to LOG --type INFO USER_CMD_LIST | |
| IFS=$IFSNL | |
| for FNAME in ${USER_SIMPLE_FILE_LIST}; do | |
| display --to LOG --type PLAIN --log-indent 6 NAME "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 -a -n "${USER_DIR_LIST}" ]; then | |
| display --to LOG --type INFO USER_DIR_LIST | |
| IFS=$IFSNL | |
| for FNAME in ${USER_DIR_LIST}; do | |
| display --to LOG --type PLAIN --log-indent 6 NAME "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| if [ -n "${USER_EXCLUDE_PROP}" ]; then | |
| display --to LOG --type INFO USER_EXCLUDE_PROP | |
| IFS=$IFSNL | |
| for FNAME in ${USER_EXCLUDE_PROP}; do | |
| display --to LOG --type PLAIN --log-indent 6 NAME "`name2text \"${FNAME}\"`" | |
| done | |
| IFS=$RKHIFS | |
| fi | |
| fi | |
| fi | |
| if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ $ROTATE_MIRRORS -eq 0 ]; then | |
| display --to LOG --type INFO CONFIG_NO_ROTATE_MIRRORS | |
| else | |
| display --to LOG --type INFO CONFIG_ROTATE_MIRRORS | |
| fi | |
| if [ $MIRRORS_MODE -eq 0 ]; then | |
| display --to LOG --type INFO CONFIG_MIRRORS_MODE0 | |
| elif [ $MIRRORS_MODE -eq 1 ]; then | |
| display --to LOG --type INFO CONFIG_MIRRORS_MODE1 | |
| else | |
| display --to LOG --type INFO CONFIG_MIRRORS_MODE2 | |
| fi | |
| if [ $UPDATE -eq 1 ]; then | |
| if [ $UPDATE_MIRRORS -eq 0 ]; then | |
| display --to LOG --type INFO CONFIG_NO_UPDATE_MIRRORS | |
| else | |
| display --to LOG --type INFO CONFIG_UPDATE_MIRRORS | |
| fi | |
| fi | |
| fi | |
| fi | |
| if [ $NOLOG -eq 0 ]; then | |
| test $CHECK -eq 0 -o $SHOW_SUMMARY -eq 0 && display --to LOG --type INFO CONFIG_LOG_FILE "${RKHLOGFILE}" | |
| if [ $VERBOSE_LOGGING -eq 0 ]; then | |
| display --to LOG --type INFO CONFIG_NO_VL | |
| else | |
| test $APPEND_LOG -eq 1 && display --to LOG --type INFO CONFIG_APPEND_LOG | |
| test $COPY_LOG_ON_ERROR -eq 1 && display --to LOG --type INFO CONFIG_COPY_LOG | |
| fi | |
| fi | |
| if [ $CHECK -eq 1 ]; then | |
| if [ -n "${KSYMS_FILE}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO KSYMS_FOUND "${KSYMS_FILE}" | |
| fi | |
| if [ ! -r "${KSYMS_FILE}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO KSYMS_UNAVAIL "${KSYMS_FILE}" | |
| fi | |
| KSYMS_FILE="" | |
| fi | |
| elif [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO KSYMS_MISSING | |
| fi | |
| if [ $SHOW_SUMMARY -eq 0 -a $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO CONFIG_NO_SHOW_SUMMARY | |
| fi | |
| # | |
| # To use syslog we must have the logger command present. | |
| # | |
| if [ -n "${USE_SYSLOG}" ]; then | |
| if [ "${USE_SYSLOG}" = "none" ]; then | |
| USE_SYSLOG="" | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SYSLOG_DISABLED | |
| fi | |
| else | |
| LOGGER_CMD=`find_cmd logger` | |
| if [ -n "${LOGGER_CMD}" ]; then | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| display --to LOG --type INFO SYSLOG_ENABLED "${USE_SYSLOG}" | |
| display --to LOG --type INFO FOUND_CMD 'logger' "${LOGGER_CMD}" | |
| fi | |
| else | |
| USE_SYSLOG="" | |
| display --to LOG --type INFO SYSLOG_NO_LOGGER | |
| fi | |
| fi | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ "${EPOCH_DATE_CMD}" = "NONE" ]; then | |
| : | |
| elif [ -n "${EPOCH_DATE_CMD}" ]; then | |
| display --to LOG --type INFO FILE_PROP_EPOCH_DATE_CMD "${EPOCH_DATE_CMD}" | |
| elif [ -n "${PERL_CMD}" ]; then | |
| display --to LOG --type INFO FILE_PROP_EPOCH_DATE_CMD "${PERL_CMD}" | |
| fi | |
| fi | |
| # | |
| # If the user wants to run the file properties checks, and the | |
| # rkhunter.dat file exists, then check the O/S info. If the | |
| # rkhunter.dat file does not exist, then this will be logged | |
| # later on. | |
| # | |
| if `check_test properties`; then | |
| if [ -s "${RKHDAT_FILE}" ]; then | |
| # | |
| # We perform a simple check on some of the stored | |
| # O/S information, and compare it to the current | |
| # info. Basically we are just seeing if the system | |
| # has changed at all because it could affect the | |
| # file properties checks. | |
| # | |
| rkh_dat_get_os_info | |
| check_os_info | |
| fi | |
| fi | |
| fi | |
| if [ $VERBOSE_LOGGING -eq 1 ]; then | |
| if [ $USE_LOCKING -eq 1 ]; then | |
| display --to LOG --type INFO LOCK_USED "$LOCK_TIMEOUT" | |
| display --to LOG --type INFO LOCK_DIR "${LOCKDIR}" | |
| else | |
| display --to LOG --type INFO LOCK_UNUSED | |
| fi | |
| fi | |
| ###################################################################### | |
| # | |
| # Start of program actions and checks | |
| # | |
| ###################################################################### | |
| # | |
| # We can now start to run the actions the user has requested on | |
| # the command-line. We run the update type commands first before | |
| # doing any full system check. | |
| # | |
| # | |
| # The user wants to update the O/S and the file properties data. | |
| # | |
| test $PROP_UPDATE -eq 1 && do_prop_update | |
| # | |
| # The user wants to update the supplied RKH *.dat files. | |
| # | |
| test $UPDATE -eq 1 && do_update | |
| # | |
| # The user wants to check for the latest program version. | |
| # | |
| test $VERSIONCHECK -eq 1 && do_versioncheck | |
| # | |
| # The user wants to check the local system for anomalies. | |
| # | |
| test $CHECK -eq 1 -o $ENDIS_OPT -eq 1 && do_system_check | |
| # | |
| # If there were errors or warnings, and the | |
| # log file is to be copied, then log it. | |
| # | |
| COPIEDLOG="" | |
| if [ $RET_CODE -gt 0 -o $WARNING_COUNT -gt 0 ]; then | |
| if [ $COPY_LOG_ON_ERROR -eq 1 -a $NOLOG -eq 0 ]; then | |
| COPIEDLOG="${RKHLOGFILE}.`date +%Y-%m-%d_%H:%M:%S`" | |
| display --to LOG --type INFO --nl SUMMARY_LOGFILE_COPIED "${COPIEDLOG}" | |
| fi | |
| fi | |
| display --to LOG --type INFO --nl RKH_ENDDATE "`date`" | |
| # | |
| # Now actually copy the log file. | |
| # | |
| test -n "${COPIEDLOG}" && cp -p "${RKHLOGFILE}" "${COPIEDLOG}" | |
| # | |
| # If the user asked to see the logfile, then show it. | |
| # | |
| test $CATLOGFILE -eq 1 && cat "${RKHLOGFILE}" | |
| IFS=$ORIGIFS | |
| exit $RET_CODE |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I fixed grep/egrep warnings in rkhunter 1.4.6.
You can see the full diff vs the original:
https://github.com/amekusa/arch-setup/compare/825d7ac..b2aceeb
To apply the patch: