#! /bin/sh
# -*- Shell-script -*-

# Check the system for vulnerabilities to some publicly available
# exploits.  This script was written to improve security.  ILLEGAL
# ACTIVITIES ARE *NOT* ENCOURAGED!

# Authors: jessen@ahand.unicamp.br
#          nelson@pangeia.com.br
#          vazquez@iqm.unicamp.br

# 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, 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 GNU Emacs; see the file COPYING.  If not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

# Please send comments/bug reports/ideas to:
# jessen@ahand.unicamp.br / nelson@pangeia.com.br

VERSION='$Id: chkexploit,v 1.13 1997/09/03 19:19:42 jessen Exp $	'

######################################################################
# Known exploits

KNOWN_EXPLOITS="
sendmail smrsh dosemu abuse dip doom minicom killmouse ldt libroot
telnetsnoopd lpr lpd messages mount_exploit umount_exploit oversize_ping
resizecons resolv nlspath restorefont rxvt suidperl splitvt crontab
locale tcpd ftpd tftpd uucp small_services pine bliss workman
SuperProbe rlogind at ghostscript XFree86 tin convfont filter fvwm
mailx pop3d SIGURG rdist pkgtool bash rcp talkd dump xlock elm cxterm
color_xterm suid_rw_partitions zgv seyon imapd bind lynx smbmount ld_so
request_route"

######################################################################
# return codes

### vulnerable binary
VULNERABLE=0

### not vulnerable, suid bit removed, exec bit removed
NOT_VULNERABLE=1

### unknow OS/Release
NOT_TESTED=2

### service not running
DISABLED=3

### trojaned/infected by virus
INFECTED=4

### not trojaned/infected by virus
NOT_INFECTED=5

### can't read binary
ERROR=6

### binary not found
NOT_FOUND=7

######################################################################
# functions

sendmail () {
DESCRIPTION="  Problem: Version dependent.
  Fix: Upgrade to latest version from ftp://ftp.sendmail.org.
"
    STATUS=${NOT_FOUND}
    SENDMAIL_OPT="-d -bv root"
    ### check for sendmail ver. 8.6.x - 8.8.6
    VULNERABLE_SENDMAIL_VERSION="Version 8\.6\.|Version 8\.7\.|\
Version 8\.8\.[0-6][\. ]?.*$"

    case ${SYSTEM} in
    "Linux")
        SENDMAIL=/usr/sbin/sendmail;;

    "FreeBSD")
        SENDMAIL=/usr/sbin/sendmail;;

    *)
        ### try this
        SENDMAIL=/usr/lib/sendmail;;
    esac

    if [ -f "${SENDMAIL}" ]
    then
      if [ ! -x "${SENDMAIL}" ]
      then
          STATUS=${ERROR}
          ERR="Can't exec ${SENDMAIL}"
      else
          if "${SENDMAIL}" "${SENDMAIL_OPT}" < /dev/null  2> /dev/null | \
            ${egrep} "${VULNERABLE_SENDMAIL_VERSION}" > /dev/null 2>&1
          then
              STATUS=${VULNERABLE}
          else
              STATUS=${NOT_VULNERABLE}
          fi
      fi
    fi

    return ${STATUS}
}

smrsh () {
DESCRIPTION="  Problem: Local users can use .forward to exec programs.
  Fix: replace /bin/sh by smrsh as your program mailer.
"
    STATUS=${DISABLED}
    SENDMAIL_CF=/etc/sendmail.cf

    if [ -f "${SENDMAIL_CF}" ]
    then
        if [ ! -r "${SENDMAIL_CF}" ]
        then
            STATUS=${ERROR}
            ERR="Can't read ${SENDMAIL_CF}"
        else
            if ${egrep} '^Mprog' "${SENDMAIL_CF}" 2> /dev/null | ${grep} \
                smrsh > /dev/null 2>&1
            then
                    STATUS=${NOT_VULNERABLE}
            else
                    STATUS=${VULNERABLE}
            fi
        fi
    fi

   return ${STATUS}
}

dosemu () {
DESCRIPTION="  Problem: Local users can read any file on the system.
  Fix: Remove SUID bit.
"
    STATUS=${NOT_FOUND}
    DOSEMU="/usr/bin/dos /usr/local/bin/dos"

    for file in ${DOSEMU}
    do
        if [ -f "${file}" ]
        then
          if [ -x "${file}" ] && is_suid root "${file}"
          then
              STATUS=${VULNERABLE}
              break
          else
              STATUS=${NOT_VULNERABLE}
          fi
        fi
    done

    return ${STATUS}
}

abuse () {
DESCRIPTION="  Problem: Local users can run arbitrary commands as root.
  Fix: Remove SUID bit.
"
    STATUS=${NOT_FOUND}
    ABUSE="/usr/lib/games/abuse/abuse.console"

    if [ -f "${ABUSE}" ]
    then
        if [ -x "${ABUSE}" ] && is_suid root "${ABUSE}"
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

dip () {
DESCRIPTION="  Problem: Local users can gain root access.
  Fix: Remove SUID bit or get the the latest version of dip.
"
    STATUS=${NOT_FOUND}
    DIP="/sbin/dip /usr/sbin/dip /usr/local/sbin/dip"
    VULNERABLE_DIP_VERSION="3\.3\.7"
    SAFE_DIP_VERSION="3\.3\.7o-uri"

    for file in ${DIP}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}" && \
                "${file}" 2> /dev/null | ${egrep} \
                "${VULNERABLE_DIP_VERSION}"\ | ${egrep} -v \
                "${SAFE_DIP_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

doom () {
DESCRIPTION="  Problem: Local users can run arbitrary commands as root.
  Fix: Remove SUID bit.
"
    STATUS=${NOT_FOUND}
    DOOM="/usr/games/doom/*doom*"

    for file in ${DOOM}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

minicom () {
DESCRIPTION="  Problem: Local users can read any file on the system.
  Fix: Remove SUID bit.
"
    STATUS=${NOT_FOUND}
    MINICOM="/usr/bin/minicom /usr/local/bin/minicom"

    for file in ${MINICOM}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

killmouse () {
DESCRIPTION="  Problem: Local users can write to arbitrary files on the system.
  Fix: Remove SUID bit.
"
    STATUS=${NOT_FOUND}
    KILLMOUSE="/usr/games/doom/killmouse /usr/games/doom/startmouse"

    for file in ${KILLMOUSE}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

ldt () {
DESCRIPTION="  Problem: Local users can gain root access.
  Fix: Upgrade to a newer Linux Kernel: >= 1.3.20.
"
    STATUS=${NOT_VULNERABLE}
    ### every Linux kernel up to 1.3.19 is vulnerable
    VULNERABLE_KERNEL_VERSION="1\.[12]\.|1\.3\.[0-9]$|1\.3\.1[0-9]$"

    if [ "${SYSTEM}" = "Linux" ]
    then
        if ${echo} ${RELEASE} | ${egrep} "${VULNERABLE_KERNEL_VERSION}" \
            > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

libroot () {
DESCRIPTION="  Problem: Non-local users can gain root access.
  Fix: Download and install the latest telnetd.
"
    STATUS=${NOT_VULNERABLE}
    TELNETD=""
    ### state.c below version 1.4 doesn't have envvarok ()
    VULNERABLE_STATE_C_VERSION="1\.[1-3] "

    if enabled_inetd_service "telnet"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for telnetd
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
                /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in `get_daemon_for_service telnet`
        do
            if [ -f "${dir}/${filename}" ]
            then
                TELNETD=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${TELNETD}" ]
    then
        STATUS=${NOT_FOUND}

    elif ${strings} "${TELNETD}" 2> /dev/null | ${grep} "state\.c" | \
        ${egrep} "${VULNERABLE_STATE_C_VERSION}" > /dev/null 2>&1
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

telnetsnoopd () {
DESCRIPTION="  Problem: Non-local users can gain root access.
  Fix: Disable telnetsnoopd or install the lastest version.
"
    STATUS=${NOT_VULNERABLE}
    TELNETSNOOPD=""
    ### state.c below version 1.4 doesn't have envvarok ()
    VULNERABLE_STATE_C_VERSION="1\.[1-3] "

    if enabled_inetd_service "telnetsnoopd"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for telnetsnoopd
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
                /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in `get_daemon_for_service telnetsnoopd`
        do
            if [ -f "${dir}/${filename}" ]
            then
                TELNETSNOOPD=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${TELNETSNOOPD}" ]
    then
        STATUS=${NOT_FOUND}

    elif ${strings} "${TELNETSNOOPD}" 2> /dev/null | ${grep} "state\.c" | \
        ${egrep} "${VULNERABLE_STATE_C_VERSION}" > /dev/null 2>&1
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

lpr () {
DESCRIPTION="  Problem: Local Users can gain root access.
  Fix: Remove the SUID bit or get the latest lpr.
"
    STATUS=${NOT_FOUND}
    LPR=/usr/bin/lpr
    VULNERABLE_LPR_VERSION="1\.1 "
    SAFE_LPR_STRING="Buffer overflow"
    LPR_WRAPPER_STRING="lpr_wrapper"
    LPR_REAL=/usr/bin/lpr.real

    if [ -f "${LPR}" ]
    then
        if [ ! -r "${LPR}" ]
        then
            STATUS=${ERROR}
            ERR="Can't read ${LPR}"
        ### test for lpr wrapper
        elif ${strings} "${LPR}" 2> /dev/null | ${grep} \
            "${LPR_WRAPPER_STRING}" > /dev/null 2>&1
        then
            if [ -x "${LPR_REAL}" ] && is_suid root "${LPR_REAL}"
            then
                STATUS=${VULNERABLE}
            else
                STATUS=${NOT_VULNERABLE}
            fi
        ### no, test the real one
        elif [ -x "${LPR}" ] && is_suid root "${LPR}" && \
            ${strings} "${LPR}" 2> /dev/null | ${grep} "lpr\.c" | \
            ${grep} "${VULNERABLE_LPR_VERSION}" > /dev/null 2>&1
        then
            if ${strings} "${LPR}" 2> /dev/null | ${grep} \
                "${SAFE_LPR_STRING}" > /dev/null 2>&1
            then
                STATUS=${NOT_VULNERABLE}
            else
                STATUS=${VULNERABLE}
            fi
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

lpd () {
DESCRIPTION="  Problem: Remote users can gain root access.
  Fix: Upgrade your FreeBSD libc.
"
    STATUS=${NOT_VULNERABLE}
    ### libc before 1997/02/25 suffer from this vulnerability.
    FREEBSD_VULNERABLE_LIBC_TIMESTAMP="199702250000"
    LIBC_DIR='/usr/lib'
    LIBC_FILE='libc.so*'
    TEST_FILE="/tmp/.timestamp.$$"

    if [ "${SYSTEM}" = "FreeBSD" ]
    then

        if [ -f "${TEST_FILE}" -o -h "${TEST_FILE}" ]
        then
            STATUS=${ERROR}
            ERR="Can't create ${TEST_FILE}: file already exist"
            return ${STATUS}
        fi

        if ${touch} -t "${FREEBSD_VULNERABLE_LIBC_TIMESTAMP}" "${TEST_FILE}"
        then
            :
        else
            STATUS=${ERROR}
            ERR="Can't create ${TEST_FILE}"
            return ${STATUS}
        fi

        if [ -n "`${find} ${LIBC_DIR} -name ${LIBC_FILE} \
            ! -newer ${TEST_FILE} 2> /dev/null`" ]
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
        ${rm} -f "${TEST_FILE}"
    fi

    return ${STATUS}
}

messages () {
DESCRIPTION="  Problem: Local users can get other users passwords.
  Fix: Keep {/var/log,/usr/adm}/messages readable only for root.
"
    STATUS=${NOT_VULNERABLE}
    MESSAGES_DIR=/usr/adm
    MESSAGES_FILE=messages
    ### read and/or write permission for others
    VULNERABLE_MESSAGES_PERM="-004"

    if [ "${SYSTEM}" = "FreeBSD" ]
    then
        MESSAGES_DIR=/var/log
        VULNERABLE_MESSAGES_PERM="-066"
    fi

    if [ -n "`${find} ${MESSAGES_DIR} ${FINDOPT} -name ${MESSAGES_FILE} \
        -perm ${VULNERABLE_MESSAGES_PERM} -print 2> /dev/null`" ]
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

mount_exploit () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Replace mount with the latest version or remove SUID bit.
"
    STATUS=${NOT_FOUND}
    VULNERABLE_MOUNT_VERSION="2\.[2-4]|2\.5j"

    if [ -f "${mount}" ]
    then
        if is_suid root "${mount}" && ${strings} "${mount}" \
            2> /dev/null | ${egrep} \
            "${VULNERABLE_MOUNT_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

umount_exploit () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Replace umount with the latest version or remove SUID bit.
"
    STATUS=${NOT_FOUND}
    VULNERABLE_UMOUNT_VERSION="2\.[2-4]|2\.5j"

    if [ -f "${umount}" ]
    then
        if is_suid root "${umount}" && ${strings} "${umount}" \
            2> /dev/null | ${egrep} \
            "${VULNERABLE_UMOUNT_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

oversize_ping () {
DESCRIPTION="  Problem: Non-local users can crash your machine.
  Fix: Upgrade your kernel to a patched version.
       Linux: >= 2.0.24  FreeBSD: >= 2.x
"
    STATUS=${NOT_VULNERABLE}
    LINUX_PATCH_LABEL="Oversized"
    SAFE_FREEBSD_KERNEL="2\.|3\."
    ### every Linux kernel up to 2.0.23 is vulnerable
    VULNERABLE_LINUX_KERNEL="1\.[1-3]\.|2\.0\.[0-9]$|2\.0\.1[0-9]$|\
2\.0\.2[0-3]$"

    case ${SYSTEM} in

    "Linux")
        if ${echo} ${RELEASE} | ${egrep} "${VULNERABLE_LINUX_KERNEL}" \
            > /dev/null 2>&1
        then
            if ${strings} /usr/src/linux/vmlinux 2> /dev/null | \
                ${grep} "${LINUX_PATCH_LABEL}" >/dev/null 2>&1
            then
                :
            else
                STATUS=${VULNERABLE}
            fi
        fi;;

    "FreeBSD")
        if ${echo} ${RELEASE} | ${egrep} -v "${SAFE_FREEBSD_KERNEL}" \
            > /dev/null 2>&1
        then
            STATUS=${NOT_TESTED}
        fi;;

    *)
        STATUS=${NOT_TESTED}
    esac

    return ${STATUS}
}

resizecons () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Disable resizeicons.
"
    STATUS=${NOT_FOUND}
    RESIZECONS="/usr/bin/resizecons"

    if [ -f "${RESIZECONS}" ]
    then
        if [ -x "${RESIZECONS}" ] && is_suid root "${RESIZECONS}"
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

resolv () {
DESCRIPTION="  Problem: Local users may read any file on the system.
  Fix: Upgrade to a Linux libc 5.4.7 or greater.
"
    STATUS=${NOT_VULNERABLE}

    if [ "${SYSTEM}" = "Linux" ]
    then
        ### this is Linux specific
        ldconfig="/sbin/ldconfig"
        LDCONFIG_OPT="-p"
        ### This should be exploitable on systems with libc < 5.4.7
        VULNERABLE_LIBC_VERSION="libc\.so\.[1-4][\. ]|libc\.so\.5\.3\.|\
libc\.so\.5\.4\.[0-6]$"

        if ${ldconfig} ${LDCONFIG_OPT} 2>&1 | ${egrep} \
            "${VULNERABLE_LIBC_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

nlspath () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Upgrade to a Linux libc 5.4.x or greater.
"
    STATUS=${NOT_VULNERABLE}

    if [ "${SYSTEM}" = "Linux" ]
    then
        ### this is Linux specific
        ldconfig="/sbin/ldconfig"
        LDCONFIG_OPT="-p"
        ### This should be exploitable on systems with libc < 5.4
        VULNERABLE_LIBC_VERSION="libc\.so\.[1-4][\. ]|libc\.so\.5\.3\."

        if ${ldconfig} ${LDCONFIG_OPT} 2>&1 | ${egrep} \
            "${VULNERABLE_LIBC_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

restorefont () {
DESCRIPTION="  Problem: the first 8KB of any file bigger than 8KB can be read.
  Fix: Disable restorefont or get the latest SVGALIB package.
"
    STATUS=${NOT_FOUND}
    RESTOREFONT=/usr/bin/restorefont
    VULNERABLE_LIBVGA_VERSION="libvga\.so\.1\.[01]\.|libvga\.so\.1\.2\.[0-9]$"

    if [ -f "${RESTOREFONT}" ]
    then
        if [ -x "${RESTOREFONT}" ] && is_suid root "${RESTOREFONT}" && \
            ldd "${RESTOREFONT}" 2> /dev/null | ${egrep} \
            "${VULNERABLE_LIBVGA_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

rxvt () {
DESCRIPTION="  Problem: Local users can gain root access.
  Fix: Remove SUID bit or get the latest version.
"
    STATUS=${NOT_FOUND}
    RXVT=/usr/X11/bin/rxvt
    VULNERABLE_RXVT_VERSION="1\.|2\.0[1-3]$"
    VULNERABLE_RXVT_OPTION="\-print\-pipe"

    if [ -f "${RXVT}" ]
    then
        if [ -x "${RXVT}" ] && is_suid root "${RXVT}" && \
            ${strings} "${RXVT}" 2> /dev/null | ${egrep} \
            "${VULNERABLE_RXVT_VERSION}" > /dev/null 2>&1 && \
            ${strings} "${RXVT}" 2> /dev/null | ${egrep} \
            "${VULNERABLE_RXVT_OPTION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

suidperl () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Remove the suid bit from the sperl binary.
"
    STATUS=${NOT_FOUND}
    SUIDPERL_FILES="/usr/bin/suidperl /usr/local/bin/suidperl \
/usr/bin/sperl* /usr/local/bin/sperl*"
    SAFE_SUIDPERL_OUTPUT="version 5\.003_97|version 5\.004"

    for SUIDPERL in ${SUIDPERL_FILES}
    do
        if [ -f "${SUIDPERL}" ]
        then
            if [ -x "${SUIDPERL}" ] && is_suid root "${SUIDPERL}"
            then
                    if "${SUIDPERL}" -v | ${egrep} "${SAFE_SUIDPERL_OUTPUT}" \
                        > /dev/null 2>&1
                    then
                        STATUS=${NOT_VULNERABLE}
                    else
                        STATUS=${VULNERABLE}
                        break
                    fi ### safe_output
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi ### -f
    done

    return ${STATUS}
}

splitvt () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Remove SUID bit from splitvt.
"
    STATUS=${NOT_FOUND}
    SPLITVT=/usr/bin/splitvt
    VULNERABLE_SPLITVT_VERSION="[01]\.[0-5][\. ]|1\.6\.[0-2] "

    if [ -f "${SPLITVT}" ]
    then
        if [ -x "${SPLITVT}" ] && is_suid root "${SPLITVT}" && \
        "${SPLITVT}" -v | ${egrep} "${VULNERABLE_SPLITVT_VERSION}" \
        > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

crontab () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Disable crontab or get the newest version.
"
    STATUS=${NOT_VULNERABLE}
    CRONTAB=/usr/bin/crontab
    VIXIE_VULNERABLE_FILE="env\.c"
    VIXIE_VULNERABLE_ENV_C_VERSION="1\.|2\.[0-6] "
    FREEBSD_CRONTAB_VULNERABLE_FILE="env\.c"
    FREEBSD_CRONTAB_VULNERABLE_ENV_C_VERSION="1\.1\.1\.1[ |$]"

    if [ -f "${CRONTAB}" ]
    then
        if [ ! -r "${CRONTAB}" ]
        then
            STATUS=${ERROR}
            ERR="Can't read ${CRONTAB}"
            return ${STATUS}
        fi
    else
        STATUS=${NOT_FOUND}
        return ${STATUS}
    fi

    ### Test for vixie cron only on Linux systems
    if [ "${SYSTEM}" = "Linux" ]
    then
        if [ -x "${CRONTAB}" ] && is_suid root "${CRONTAB}" && ${strings} \
        "${CRONTAB}" 2> /dev/null | ${egrep} "${VIXIE_VULNERABLE_FILE}" | \
        ${egrep} "${VIXIE_VULNERABLE_ENV_C_VERSION}" > /dev/null 2>&1
      then
        STATUS=${VULNERABLE}
        return ${STATUS}
      else
        STATUS=${NOT_VULNERABLE}

      fi
    elif [ "${SYSTEM}" = "FreeBSD" ]
    then

        if [ -x "${CRONTAB}" ] && is_suid root "${CRONTAB}" && \
            ${strings} "${CRONTAB}" 2> /dev/null | ${egrep} \
            "${FREEBSD_CRONTAB_VULNERABLE_FILE}" | ${egrep} \
            "${FREEBSD_CRONTAB_VULNERABLE_ENV_C_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

locale () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Upgrade your FreeBSD kernel: >= 2.1.7.
"
    STATUS=${NOT_VULNERABLE}
    VULNERABLE_LOCALE_STRING="PATH_LOCALE"
    VULNERABLE_LIBS="/lib/libc.so.*"

    for lib in ${VULNERABLE_LIBS}
    do
        if ${strings} "${lib}" 2> /dev/null |
           ${egrep} "${VULNERABLE_LOCALE_STRING}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
            break
        fi
    done

    return ${STATUS}
}

tcpd () {
DESCRIPTION="  Problem: Older versions don't have proper anti source-routing \
protection.
  Fix: Get a newer version of tcpd from ftp://ftp.win.tue.nl/pub/security/.
"
    STATUS=${VULNERABLE}
    ### version 7.6 remove source routing vulnerability
    NOT_VULNERABLE_VERSION="patchlevel 7\.6"
    TCPD="`${egrep} -v '^#' /etc/inetd.conf 2> /dev/null | \
    ${grep} tcpd | head -1 | ${awk} '{ print $6 }'`"

    if ${echo} "${TCPD}" | ${grep} -v "tcpd" > /dev/null
    then
         STATUS=${NOT_FOUND}
    elif ${strings} "${TCPD}" 2> /dev/null | ${grep} \
        "${NOT_VULNERABLE_VERSION}" > /dev/null 2>&1
    then
        STATUS=${NOT_VULNERABLE}
    fi

    return ${STATUS}
}

ftpd () {
DESCRIPTION="  Problem: Non-local users may gain access to the system.
  Fix: Download and install the latest version of ftpd.
"
    STATUS=${VULNERABLE}
    FTPD=""
    ### not vulnerable wuftp have sigfix.c
    WUFTPD_LABEL="Version.*wu"
    SAFE_WUFTPD_LABEL="academ\[BETA-1[2-4]\]"
    SAFE_VENEMA_FTPD_LABEL="_enable_signalling"
    VULNERABLE_FREEBSD_FTPD_LABEL="ENABLE_STARTUP_LOCALE"

    if enabled_inetd_service "ftp"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for ftpd
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
            /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in wu.ftpd ftpd in.ftpd
        do
            if [ -f "${dir}/${filename}" ]
            then
                FTPD=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${FTPD}" ]
    then
        STATUS=${NOT_FOUND}

    ### wuftpd
    elif ${strings} "${FTPD}" 2> /dev/null | ${egrep} "${WUFTPD_LABEL}" \
        >/dev/null 2>&1
    then
       if ${strings} "${FTPD}" 2> /dev/null | ${egrep} \
            "${SAFE_WUFTPD_LABEL}" > /dev/null 2>&1
       then
          STATUS=${NOT_VULNERABLE}
       fi

    ### Venema's ftp
    elif ${strings} "${FTPD}" 2> /dev/null | ${grep} \
        "${SAFE_VENEMA_FTPD_LABEL}" >/dev/null 2>&1
    then
        STATUS=${NOT_VULNERABLE}

    ### FreeBSD ftpd
    elif ${strings} "${FTPD}" 2> /dev/null | ${grep} \
        "${VULNERABLE_FREEBSD_FTPD_LABEL}" >/dev/null 2>&1
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

tftpd () {
DESCRIPTION="  Problem: Unsafe service.  Do you really need it?
  Fix: Disable tftp in /etc/inetd.conf or protect it using tcpd.
"
    STATUS=${DISABLED}

    if enabled_inetd_service "tftp"
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

uucp () {
DESCRIPTION="  Problem: Unsafe service.  Do you really need it?
  Fix: Disable uucp in /etc/inetd.conf or protect it using tcpd.
"
    STATUS=${DISABLED}

    if enabled_inetd_service "uucp"
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

small_services () {
DESCRIPTION="  Problem: Non-local users can crash your machine.
  Fix: Turn off echo, discard, daytime, chargen and time from /etc/inetd.conf.
"
    STATUS=${DISABLED}

    for service in echo discard daytime chargen time
    do
        if enabled_inetd_service "${service}"
        then
            STATUS=${VULNERABLE}
            break
        fi
    done

    return ${STATUS}
}

pine () {
DESCRIPTION="  Problem: Local users can edit files own by the person reading \
mail via Pine.
  Fix: Disable Pine or upgrade to version 3.95
"
    STATUS=${NOT_FOUND}
    PINE="/usr/bin/pine /usr/local/bin/pine"
    ### pine versions before 3.95 are vulnerable
    VULNERABLE_PINE_VERSION="Version 2\.|Version 3\.[0-8]. |Version 3\.9[0-4] "

    for file in ${PINE}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && ${strings} "${file}" 2> /dev/null | \
                ${egrep} "${VULNERABLE_PINE_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

bliss () {
DESCRIPTION="  Problem: Infected programs will not run.
  Fix: Check for /tmp/.bliss and disable any file in that list.
"
    STATUS=${NOT_INFECTED}
    BLISS_DIR="/tmp/.bliss"

    if [ -n "`${find} ${BLISS_DIR} -type d -prune -print 2> /dev/null`" ]
    then
        STATUS=${INFECTED}
    fi

    return ${STATUS}
}

workman () {
DESCRIPTION="  Problem: workman can be used to make any file on the system \
world-writable.
  Fix: Remove SUID bit from workman.
"
    STATUS=${NOT_FOUND}
    WORKMAN="/usr/openwin/bin/workman /usr/X11/bin/workman \
/usr/local/bin/workman"

    for file in ${WORKMAN}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

SuperProbe () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove the SUID bit.
"
    STATUS=${NOT_FOUND}
    SUPERPROBE="/usr/X11/bin/SuperProbe /usr/X11R6/bin/SuperProbe"

    for file in ${SUPERPROBE}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

xlock () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove suid bit from xlock or install the latest version.
"
    STATUS=${NOT_FOUND}
    XLOCK="/usr/X11R6/bin/xlock /usr/X11/bin/xlock /usr/local/bin/xlock"
    ### xlock versions before 4.02 are vulnerable
    NOT_VULNERABLE_XLOCK_VERSION="xlock\.c.*4\.02"

    for file in ${XLOCK}
    do
        if [ -f "${file}" ]
        then
            if [ ! -r "${file}" ]
            then
                STATUS=${ERROR}
                ERR="Can't read ${file}"
                break
            elif [ -x "${file}" ] && is_suid root "${file}"
            then
                if ${strings} "${file}" 2> /dev/null | ${egrep} \
                    "${NOT_VULNERABLE_XLOCK_VERSION}" > /dev/null 2>&1
                    then
                        STATUS=${NOT_VULNERABLE}
                    else
                        STATUS=${VULNERABLE}
                        break
                    fi
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

rlogind () {
DESCRIPTION="  Problem: Non-local users can get root access.
  Fix: Disable rlogin in /etc/inetd.conf or install the latest version.
"
    STATUS=${NOT_VULNERABLE}
    RLOGIND=""
    ### rlogind.c version until 1.13 have the problem
    VULNERABLE_RLOGIND_C_VERSION="1\.[0-9] |1\.1[0-3] "

    if enabled_inetd_service "login"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    if [ "${SYSTEM}" = "Linux" ]
    then

        ### check for rlogind
        for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
                /usr/local/sbin /usr/local/bin /usr/etc /etc
        do
            for filename in `get_daemon_for_service login`
            do
                if [ -f "${dir}/${filename}" ]
                then
                    RLOGIND=$dir/$filename
                    break 2
                fi
            done
        done

        if [ -z "${RLOGIND}" ]
        then
            STATUS=${NOT_FOUND}

        elif ${strings} "${RLOGIND}" 2> /dev/null | ${grep} "rlogind\.c" | \
            ${egrep} "${VULNERABLE_RLOGIND_C_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        fi

    fi

    return ${STATUS}
}

at() {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: chmod 700 /var/spool/atjobs and upgrade the 'at'
       command to version 2.7 or newer.
"
    STATUS=${NOT_VULNERABLE}
    AT=/usr/bin/at
    AT_SPOOL_DIR=/var/spool/atjobs
    VULNERABLE_ATJOBS_PERM="-001"
    ### at versions before 2.7 are vulnerable
    VULNERABLE_AT_VERSION="1\.|2\.[0-8]"

    if [ "${SYSTEM}" = "Linux" ]
    then
        STATUS=${NOT_FOUND}

        if [ -f "${AT}" ]
        then
            if [ -x "${AT}" ] && "${AT}" -V 2>&1 | ${egrep} \
                "${VULNERABLE_AT_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi

        if [ -n "`${find} ${AT_SPOOL_DIR} ${FINDOPT} -type d \
            -perm ${VULNERABLE_ATJOBS_PERM} -print 2> /dev/null`" ]
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

ghostscript () {
DESCRIPTION="  Problem: The user is vulnerable to attacks via Postscript code.
  Fix: Upgrade Ghostscript to the latest version.
"
    STATUS=${NOT_FOUND}
    GS="/usr/bin/gs /usr/local/bin/gs"
    ### ghostscript version 1.4 is vulnerable
    VULNERABLE_GS_VERSION="version 1\.4 "

    for file in ${GS}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && "${file}" -h 2> /dev/null | ${egrep} \
                "${VULNERABLE_GS_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

XFree86 () {
DESCRIPTION="  Problem: Local users may read/overwrite arbitrary files.
  Fix: Upgrade XFree 3.1.2. http://www.xfree86.org.
"
    STATUS=${NOT_FOUND}
    XFREE86="/usr/X11R6/bin/XF86_* /usr/X11/bin/XF86_*"
    XFREE86_OPT="-showconfig"
    ### XFree86 3.1.2 version is vulnerable
    VULNERABLE_XFREE86_VERSION="Version 3\.1\.2 "

    for file in ${XFREE86}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}" && \
                "${file}" "${XFREE86_OPT}" 2>&1 | ${egrep} \
                "${VULNERABLE_XFREE86_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

tin () {
DESCRIPTION="  Problem: A tin user can have their files perms changed to rw.
  Fix: Disable tin 1.2, recompile with -DDONT_LOG_USER or upgrade to the
       latest version.
"
    STATUS=${NOT_FOUND}
    TIN="/usr/bin/tin /usr/local/bin/tin"
    ### tin version 1.2 is vulnerable with .tin_log file.
    VULNERABLE_TIN_VERSION="tin 1\.2 "
    VULNERABLE_TIN_FEATURE="\.tin_log"

    for file in ${TIN}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && ${file} -H 2> /dev/null < /dev/null | \
                ${egrep} "${VULNERABLE_TIN_VERSION}" > /dev/null 2>&1 && \
                ${strings} "${file}" | ${egrep} "${VULNERABLE_TIN_FEATURE}" \
                >/dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

convfont () {
DESCRIPTION="  Problem: Local users can add themselves to /etc/{passwd,shadow}.
  Fix: Remove SUID bit or upgrade to the latest SVGALIB package.
"
    STATUS=${NOT_FOUND}
    CONVFONT="/usr/sbin/convfont /usr/bin/convfont /usr/local/bin/convfont"
    VULNERABLE_LIBVGA_VERSION="libvga\.so\.1\.[01]\.|libvga\.so\.1\.2\.[0-9]$"

    for file in ${CONVFONT}
    do
        if [ -f ${file} ]
        then
            if [ -x "${file}" ] && is_suid root "${file}" && \
            ${ldd} "${file}" 2> /dev/null | ${egrep} \
            "${VULNERABLE_LIBVGA_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

filter () {
DESCRIPTION="  Problem: Local users can read users mail.
  Fix: Disable filter version 2.4 or get the latest version.
"
    STATUS=${NOT_FOUND}
    FILTER="/usr/bin/filter /usr/local/bin/filter"
    ### filter version 1.4 is vulnerable
    VULNERABLE_FILTER_VERSION="elm2\.[0-4]"

    for file in ${FILTER}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && ${strings} "${file}" 2> /dev/null | \
            ${egrep} "${VULNERABLE_FILTER_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

elm () {
DESCRIPTION="  Problem: Local users can gain mail group access.
  Fix: Remove SGID bit or install elm newer than 2.4 PL25.
"
    STATUS=${NOT_FOUND}
    ELM="/usr/bin/elm /usr/local/bin/elm"
    ### elm version up to 2.4 PL25 is vulnerable
    VULNERABLE_ELM_OUTPUT="Elm 2\.3[ ,]|Elm 2\.4 PL([0-9]|1[0-9]|2[0-5])[ ,]"

    for file in ${ELM}
    do
        if [ -f ${file} ]
        then
            if [ -x ${file} ] && is_sgid mail ${file} && "${file}" -v 2>&1 | \
                ${egrep} "${VULNERABLE_ELM_OUTPUT}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

fvwm () {
DESCRIPTION="  Problem: Users may be able to execute commands as other users.
  Fix: Disable fvwm 1.24 or upgrade to the latest version.
"
    STATUS=${NOT_FOUND}
    FVWM="/usr/X11R6/bin/fvwm /usr/X11/bin/fvwm /usr/local/X11/bin/fvwm \
/usr/local/bin/fvwm"
    ### FVWM 1.24 is vulnerable
    VULNERABLE_FVWM_VERSION="Ver 1\.24"

    for file in ${FVWM}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && ${strings} "${file}" 2> /dev/null | \
                ${egrep} "${VULNERABLE_FVWM_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

mailx () {
DESCRIPTION="  Problem: Mail can be read, edited and sent.
  Fix: Disable mailx 5.5 or upgrade to the latest version.
"
    STATUS=${NOT_FOUND}
    MAILX=/bin/mailx
    ### MAILX 5.5 is vulnerable
    VULNERABLE_MAILX_VERSION="5\.5 "

    if [ -f "${MAILX}" ]
    then
        if [ -x "${MAILX}" ] && ${strings} "${MAILX}" 2> /dev/null | \
            ${egrep} "${VULNERABLE_MAILX_VERSION}" > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        else
            STATUS=${NOT_VULNERABLE}
        fi
    fi

    return ${STATUS}
}

pop3d () {
DESCRIPTION="  Problem: Any person using pop3d to get mail can have their \
mail stolen.
  Fix: Disable pop3d in /etc/inetd.conf or get a newer pop3d daemon.
"
    STATUS=${NOT_VULNERABLE}
    POP3D=""
    VULNERABLE_POP3D_STRING=" POP3 3\.0"

    if enabled_inetd_service "pop3"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for pop3d
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
            /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in `get_daemon_for_service pop3`
        do
            if [ -f "${dir}/${filename}" ]
            then
                POP3D=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${POP3D}" ]
    then
        STATUS=${NOT_FOUND}

    elif [ -x "${POP3D}" ]
    then

        POP3D_OUTPUT="`"${POP3D}" <<EOF
QUIT
EOF`"

        if ${echo} "${POP3D_OUTPUT}" | ${egrep} "${VULNERABLE_POP3D_STRING}"
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

SIGURG () {
DESCRIPTION="  Problem: User can kill processes that not belong to them.
  Fix: Upgrade to a newer Linux Kernel: > 1.3.6.
"
    STATUS=${NOT_VULNERABLE}
    ### every Linux kernel up to 1.3.6 is vulnerable
    VULNERABLE_KERNEL_VERSION="1\.[12]\.|1\.3\.[0-6]$"

    if [ "${SYSTEM}" = "Linux" ]
    then
        if ${echo} ${RELEASE} | ${egrep} "${VULNERABLE_KERNEL_VERSION}" \
            > /dev/null 2>&1
        then
            STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

rdist () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Remove SUID bit from rdist.
"
    STATUS=${NOT_FOUND}
    RDIST="/usr/bin/rdist /usr/local/bin/rdist /usr/sbin/rdist"

    for file in ${RDIST}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

pkgtool () {
DESCRIPTION="  Problem: Local users may gain root access.
  Fix: Remove SUID bit from pkgtool.
"
    STATUS=${NOT_FOUND}
    PKGTOOL="/sbin/pkgtool /sbin/cpkgtool /usr/lib/setup/pkgtool \
/usr/lib/setup/cpkgtool"

    for file in ${PKGTOOL}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

bash () {
DESCRIPTION="  Problem: Any user may run commands as the person whom owns \
the shell.
  Fix: Upgrade to a version newer than 1.14.6.
"
    STATUS=${NOT_FOUND}
    BASH="/bin/bash /usr/bin/bash /usr/local/bin/bash"
    VULNERABLE_BASH_VERSION="version 1\.14\.[0-6]"

    for file in ${BASH}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && ${strings} "${file}" 2> /dev/null |
               ${egrep} "${VULNERABLE_BASH_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

rcp () {
DESCRIPTION="  Problem: Non-local users can get root access.
  Fix: Don't run any programs as UID/GID 65535.
"
    STATUS=${NOT_VULNERABLE}
    ID=65535

    if ${grep} nobody /etc/passwd 2> /dev/null | ${cut} -d':' -f3 | \
        ${grep} ${ID} > /dev/null
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

talkd () {
DESCRIPTION="  Problem: Non-local user may be able to execute commands \
remotely.
  Fix: Disable talkd in /etc/inetd.conf or install it from NetKit-0.09.tar.gz.
"
    STATUS=${NOT_VULNERABLE}
    TALKD=""
    ### talkd.c version up to 1.2 have the problem
    VULNERABLE_TALKD_C_VERSION="1\.[0-2] "

    if enabled_inetd_service "talk"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for talkd
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
            /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in `get_daemon_for_service talk`
        do
            if [ -f "${dir}/${filename}" ]
            then
                TALKD=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${TALKD}" ]
    then
        STATUS=${NOT_FOUND}

    elif ${strings} "${TALKD}" 2> /dev/null | ${grep} "talkd\.c" | \
        ${egrep} "${VULNERABLE_TALKD_C_VERSION}" > /dev/null 2>&1
    then
        STATUS=${VULNERABLE}
    fi

    return ${STATUS}
}

dump () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove the SUID bit.
"
    STATUS=${NOT_FOUND}
    DUMP="/sbin/dump /usr/sbin/dump"

    for file in ${DUMP}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

cxterm () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove the SUID bit.
"
    STATUS=${NOT_FOUND}
    CXTERM="/usr/X11/bin/cxterm /usr/X11R6/bin/cxterm"

    for file in ${CXTERM}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

color_xterm () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove the SUID bit.
"
    STATUS=${NOT_FOUND}
    COLOR_XTERM="/usr/X11/bin/color_xterm /usr/X11R6/bin/color_xterm"

    for file in ${COLOR_XTERM}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

suid_rw_partitions () {
DESCRIPTION="  Problem: Local users can create and exec suid binaries.
  Fix: Mount public writable partitions with nosuid option.
"
    STATUS=${NOT_FOUND}
    NOSUID_PARTITIONS_FOUND="`${mount} | ${grep} nosuid | ${awk} '{print $3}'`"
    DIRECTORY_LIST="/tmp /var/tmp /home"

    for dir in ${DIRECTORY_LIST}
    do
        if [ -d "${dir}" ]
        then
            RW_DIRECTORY_LIST="${RW_DIRECTORY_LIST} ${dir}"
        fi
    done

    for dir in ${RW_DIRECTORY_LIST}
    do
        STATUS=${VULNERABLE}
        for partition in ${NOSUID_PARTITIONS_FOUND}
        do
            if ${echo} "${dir}" | ${egrep} "^${partition}" > /dev/null 2>&1
            then
                STATUS=${NOT_VULNERABLE}
                break
            fi
        done
    done

    return ${STATUS}
}

zgv () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: remove the SUID bit.
"
    STATUS=${NOT_FOUND}
    ZGV="/usr/bin/zgv /usr/local/bin/zgv"

    for file in ${ZGV}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && is_suid root "${file}"
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

seyon () {
DESCRIPTION="  Problem: Local users can get euid/egid of whatever seyon is \
suid/sgid to.
  Fix: remove the SUID/SGID bit.
"
    STATUS=${NOT_FOUND}
    SEYON="/usr/X11/bin/seyon /usr/X11R6/bin/seyon /usr/local/X11/bin/seyon"

    for file in ${SEYON}
    do
        if [ -f "${file}" ]
        then
            if [ -x "${file}" ] && [ -g "${file}" -o -u "${file}" ]
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

imapd () {
DESCRIPTION="  Problem: Non-local users may gain root or local access.
  Fix: Disable imapd in /etc/inetd.conf or get the newest version.
"
    STATUS=${VULNERABLE}
    IMAPD=""
    SAFE_IMAPD_STRING="IMAP4rev1"

    if enabled_inetd_service "imap"
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    ### check for IMAPD
    for dir in /usr/sbin /usr/libexec /usr/local/libexec /sbin \
            /usr/local/sbin /usr/local/bin /usr/etc /etc
    do
        for filename in `get_daemon_for_service imap`
        do
            if [ -f "${dir}/${filename}" ]
            then
                IMAPD=$dir/$filename
                break 2
            fi
        done
    done

    if [ -z "${IMAPD}" ]
    then
        STATUS=${NOT_FOUND}

    elif ${strings} "${IMAPD}" 2> /dev/null | ${egrep} -i \
        "${SAFE_IMAPD_STRING}" > /dev/null 2>&1
    then
        STATUS=${NOT_VULNERABLE}
    fi

    return ${STATUS}
}

bind () {
DESCRIPTION="  Problem: Vulnerable Cache.
  Fix: Upgrade to a newer 4.9.6/8.1.1 version.
"
    STATUS=${NOT_FOUND}
    BIND="/usr/sbin/named"
    ### every bind until 4.9.6/8.1.1 are vulnerables
    NOT_VULNERABLE_BIND_VERSION="^@\(#\)named 4\.9\.6|^@\(#\)named 8\.1\.1"
    NAMED_BOOT="/etc/named.boot"
    NAMED_CONF="/etc/named.conf"

    if [ -f "${NAMED_BOOT}" -o -f "${NAMED_CONF}" ]
    then
        :
    else
        STATUS=${DISABLED}
        return ${STATUS}
    fi

    if [ -f "${BIND}" ]
    then

        if ${strings} "${BIND}" | ${egrep} "${NOT_VULNERABLE_BIND_VERSION}" \
            > /dev/null 2>&1
            then
                STATUS=${NOT_VULNERABLE}
            else
                STATUS=${VULNERABLE}
        fi
    fi

    return ${STATUS}
}

lynx () {
DESCRIPTION="  Problem: Local users can execute arbitrary commands.
  Fix: Install a patch from http://www.crl.com/~subir/lynx.html.
"
    STATUS=${NOT_FOUND}
    LYNX="/usr/bin/lynx /usr/local/bin/lynx"
    ### All Un*x versions of Lynx through 2.7.1 are vulnerable.
    VULNERABLE_LYNX_VERSION="Version 1\.|2\.[0-6]([. ]|$)|2\.7( |\.[0-1] |$)"

    for file in ${LYNX}
    do
        if [ -f ${file} ]
        then
            if [ -x ${file} ] && "${file}" -version 2>&1 | ${egrep} \
                "${VULNERABLE_LYNX_VERSION}" > /dev/null 2>&1
            then
                STATUS=${VULNERABLE}
                break
            else
                STATUS=${NOT_VULNERABLE}
            fi
        fi
    done

    return ${STATUS}
}

smbmount () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Upgrade your Linux smbmount to version 2.0.2 or later.
"
    STATUS=${NOT_VULNERABLE}
    SMBMOUNT="/sbin/smbmount /usr/bin/smbmount"
    VULNERABLE_SMBMOUNT_VERSION='Version 0\.|Version 2\.0\.[0-1]$'

    if [ "${SYSTEM}" = "Linux" ]
    then
        for file in ${SMBMOUNT}
        do
            if [ -f "${file}" ]
            then
                if [ -x "${file}" ] && is_suid root "${file}" && \
                    "${file}" -h 2> /dev/null | ${egrep} \
                    "${VULNERABLE_SMBMOUNT_VERSION}" > /dev/null 2>&1
                then
                        STATUS=${VULNERABLE}
                        break
                else
                        STATUS=${NOT_VULNERABLE}
                fi
            else
                STATUS=${NOT_FOUND}
            fi
        done
    fi

    return ${STATUS}
}

ld_so () {
DESCRIPTION="  Problem: Local users can get root access.
  Fix: Upgrade your Linux ld.so to version 1.9.3 or later.
"
    STATUS=${NOT_VULNERABLE}
    LD_SO=/lib/ld\.so
    VERSION_REGEXP='^.\...*\.'
    VULNERABLE_LD_SO_VERSION='1\.[6-8]\.|1\.9\.[0-2]$'

    if [ "${SYSTEM}" = "Linux" ]
    then
       STATUS=${NOT_FOUND}
       if [ -f "${LD_SO}" ]
       then
          if ${strings} "${LD_SO}" 2> /dev/null | ${egrep} \
            "${VERSION_REGEXP}" | ${head} -1 | ${egrep} \
            "${VULNERABLE_LD_SO_VERSION}" > /dev/null 2>&1
          then
              STATUS=${VULNERABLE}
          else
              STATUS=${NOT_VULNERABLE}
          fi
       fi
    fi

    return ${STATUS}
}

request_route () {
DESCRIPTION="  Problem: Local users may overwrite any file on the system.
  Fix: remove /sbin/request-route.
"
    STATUS=${NOT_VULNERABLE}
    REQUEST_ROUTE="/sbin/request-route"

    if [ "${SYSTEM}" = "Linux" ]
    then
        if [ -f "${REQUEST_ROUTE}" ]
        then
            REQUEST_ROUTE_FILENAME=`${basename} ${REQUEST_ROUTE}`
            REQUEST_ROUTE_DIRNAME=`${dirname} ${REQUEST_ROUTE}`

            if [ -x "${REQUEST_ROUTE}" -o -n \
                "`${find}  ${REQUEST_ROUTE_DIRNAME} -name \
                ${REQUEST_ROUTE_FILENAME} -perm +500 -print 2> /dev/null`" ]
            then
                STATUS=${VULNERABLE}
            else
                STATUS=${NOT_VULNERABLE}
            fi
        else
            STATUS=${NOT_FOUND}
        fi
    fi

    return ${STATUS}
}

######################################################################
# test if a given service is enabled in /etc/inetd.conf
enabled_inetd_service () {

    INETD="/etc/inetd.conf"

    if ${egrep} "${L_REGEXP}$1${R_REGEXP}" "${INETD}" 2> /dev/null | \
        ${egrep} -v "^#" > /dev/null 2>&1
    then
        return 0
    else
        return 1
    fi
}

######################################################################
# return daemon basename for a given service in inetd.conf
get_daemon_for_service () {

    INETD="/etc/inetd.conf"
    DAEMON=`${egrep} "${L_REGEXP}$1${R_REGEXP}" "${INETD}" 2> /dev/null | \
    ${egrep} -v "^#" | ${awk} '{print $7}' 2> /dev/null`

    ${echo} `${basename} ${DAEMON}`
}

######################################################################
# test if a given file is suid to a given user
is_suid () {

    OWNER=$1
    PERM="-4000"
    DIR=`${dirname} $2`
    FILE=`${basename} $2`

    if [ -n "`${find} ${DIR} ${FINDOPT} -name ${FILE} -perm ${PERM} \
        -user ${OWNER} -print 2> /dev/null`" ]
    then
        return 0
    else
        return 1
    fi
}

######################################################################
# test if a given file is sgid to a given group
is_sgid () {

    GROUP=$1
    PERM="-2000"
    DIR=`${dirname} $2`
    FILE=`${basename} $2`

    if [ -n "`${find} ${DIR} ${FINDOPT} -name ${FILE} -perm ${PERM} \
        -group ${GROUP} -print 2> /dev/null`" ]
    then
        return 0
    else
        return 1
    fi
}

######################################################################
# our which(1)
loc () {
    thing=$1
    shift
    dflt=$1
    shift
    for dir in $*; do
            case "$thing" in
            .)
            if test -d $dir/$thing; then
                    echo $dir
                    exit 0
            fi
            ;;
            *)
            for thisthing in $dir/$thing; do
                    :
            done
            if test -f $thisthing; then
                    echo $thisthing
                    exit 0
            fi
            ;;
            esac
    done
    echo $dflt
    exit 1
}

######################################################################
# main

### check for some binaries first
cmdlist="
echo
uname
strings
grep
egrep
find
dirname
basename
awk
cut
expr
mount
umount
ldd
touch
rm
head
"
pth=`echo $PATH | sed -e "s/:/ /g"`
pth="$pth /sbin /usr/sbin /lib /usr/lib"
for file in $cmdlist; do
	xxx=`loc $file $file $pth`
	eval $file=$xxx
	case "$xxx" in
	/* | ./*)

                if [ ! -x "${xxx}" ]
                then
                    echo >&2 "chkexploit: Can't exec \`$xxx'."
                    exit 1
                fi
		;;
	*)
		echo >&2 "chkexploit: Can't find \`$file'."
		exit 1
		;;
	esac
done

SHOW_NOT_VULNERABLE=t
EXPLOIT_COUNT=0

while :
do
	case $1 in
        -d | --debug)      DEBUG=t;;
        -l | --list)	   ${echo} "Known exploits: ${KNOWN_EXPLOITS}"
                           exit 0;;

        -v | --version)    ${echo} ${VERSION}
                           exit 0;;
        -V | --vulnerable) SHOW_NOT_VULNERABLE=f
                           QUIET=t;;

        -q | --quiet)      QUIET=t;;

	-h | --help | -*) ${echo} >&2 "Usage: chkexploit [options] [exploit ...]
Options:
        -h, --help        show this help and exit
        -v, --version     show version and exit
        -q, --quiet       quiet.  Do not show exploit descriptions
        -V, --vulnerable  show only vulnerable exploits
        -l, --list        list known vulnerabilities
        -d, --debug       debug"
		exit 0;;
	*)	break
	esac

	shift
done

SYSTEM="`${uname} -s`"
RELEASE="`${uname} -r`"

### `-w' is not a portable option to grep/egrep
### We can define a workaround using regexps
L_REGEXP='(^|[^A-Za-z0-9_])'
R_REGEXP='([^A-Za-z0-9_]|$)'

case ${SYSTEM} in
   "FreeBSD") FINDOPT="-follow";;
   "Linux")   FINDOPT="-follow -prune";;
esac

if [ $# -gt 0 ]
then
    ### check only exploits supplied as arguments
    for arg in $*
    do
        ### check if is a known exploit name
        if ${echo} ${KNOWN_EXPLOITS} | ${egrep} -v \
            "${L_REGEXP}${arg}${R_REGEXP}" > /dev/null 2>&1
        then
            ${echo} >&2 "chkexploit: \`${arg}': not a known exploit name"
            exit 1
        fi
    done
    LIST=$*
else
    ### check all the known exploits
    LIST=${KNOWN_EXPLOITS}
fi

for exploit in ${LIST}
do

    if [ "${DEBUG}" = "t" ] ;then
        set -x
    fi

    ### test the exploit
    ${exploit}

    case $? in
    ${VULNERABLE})
        ${echo} "${exploit}: VULNERABLE"
        EXPLOIT_COUNT=`${expr} ${EXPLOIT_COUNT} + 1`
        ;;

    ${NOT_VULNERABLE})
        if [ "${SHOW_NOT_VULNERABLE}" = "t" ]
        then
            ${echo} "${exploit}: Not vulnerable"
        fi;;

    ${NOT_TESTED})
        ${echo} "${exploit}: NOT TESTED";;

    ${DISABLED})
        if [ "${SHOW_NOT_VULNERABLE}" = "t" ]
        then
            ${echo} "${exploit}: Disabled"
        fi;;

    ${INFECTED})
        ${echo} "${exploit}: INFECTED"
        EXPLOIT_COUNT=`${expr} ${EXPLOIT_COUNT} + 1`
        ;;

    ${NOT_INFECTED})
        if [ "${SHOW_NOT_VULNERABLE}" = "t" ]
        then
            ${echo} "${exploit}: Not Infected"
        fi;;

    ${ERROR})
        ${echo} "${exploit}: ERROR: ${ERR}";;

    ${NOT_FOUND})
        if [ "${SHOW_NOT_VULNERABLE}" = "t" ]
        then
            ${echo} "${exploit}: Not Found"
        fi;;
    esac

    ### show exploit description if not in quiet mode
    if [ "${QUIET}" = "t" ]
    then
        :
    else
        ${echo} "${DESCRIPTION}"
    fi
done

    exit ${EXPLOIT_COUNT}

### chkexploit ends here
