首页 > 代码库 > Rootkit Hunter Sourcecode Learning

Rootkit Hunter Sourcecode Learning

目录

1. Rootkit Hunter Introduce2. Source Code Anylist

 

1. Rootkit Hunter Introduce

rkhunter (Rootkit Hunter) is a Unix-based tool that scans for

1. rootkits2. backdoors3. possible local exploits

It does this by

1. comparing SHA-1 hashes of important files with known good ones in online databases2. searching for default directories (of rootkits)3. searching for wrong permissions4. searching for hidden files5. searching for suspicious strings in kernel modules6. searching for special tests for Linux and FreeBSD

Relevant Link:

http://en.wikipedia.org/wiki/Rkhunterhttp://netsecurity.51cto.com/art/201012/240038.htm

 

2. Source Code

rkhunter的源代码是bash代码,有2w多行,我们以逻辑功能进行划分,分开来学习

总体来说,rkhunter的代码逻辑流程如下

do_system_check -> do_system_check_initialisation -> do_system_commands_checks -> do_rootkit_checks -> do_network_checks -> do_local_host_checks -> do_app_checks

rkhunter.sh

/*该函数是用来检查系统的入口函数,它依次调用以下这些子函数来检查系统:*/do_system_check() {      display --to LOG --type PLAIN --nl CHECK_START     /*    do_system_check_initialisation()负责初始化rkhunter进行rootkit检测需要使用到的文件名、路径变量    这里要重点理解一下:     rkhunter进行rootkit检测的一个很核心的思想就是"文件名、路径匹配",即如果linux系统上存在某个rootkit,则它一定会创建某种具有特定特征的路径以及文件    总体来说,rkhunter的检测点如下:    1. 检查已知的rootkit的文件名、路径特征    例如: Dica-Kit (T0rn variant) Rootkit    它包含如下路径、以及文件名        1) /lib/.sso        2) /lib/.so        3) /var/run/...dica/clean        4) /var/run/...dica/dxr    这意味着rkhunter会去扫描是否存在这些目录、以及目录下是否有指定的可疑rootkit文件存在    2. Miscellaneous login backdoors(login后门)        1) /bin/.login        2) /sbin/.login    3. Evil strings(可能存在安全风险的可疑字符串)    例如:        1) init:backdoor:Suckit Rootkit (backdoored init file)        2) init:/usr/bin/rcpc:Portacelo Rootkit        3) init:/usr/sbin/login:trNkit Rootkit ulogin    4. Possible rootkit files and directories(疑似rootkit文件、目录)        1) file:/usr/lib64/libkeyutils.so.1.9:Spam tool component        2) dir:/dev/ptyas:Langsuir installation directory    5. System startup file pathnames(系统启动路径)    很多rootkit会将启动代码放在系统的自动启动路径中,随系统启动自动启动        1) /etc/rc.d        2) /etc/rc.local        3) /usr/local/etc/rc.d        4) /usr/local/etc/rc.local        5) /etc/conf.d/local.start        6) /etc/init.d        7) /etc/inittab    6. SNIFFER_FILES(可疑嗅探文件检测)    很多rootkit带有嗅探数据报的功能        1) /usr/lib/libice.log        2) /dev/prom/sn.l        3) /dev/fd/.88/zxsniff.log    7. Known bad Linux kernel modules(已知的LKM rootkit模块检测)        1) adore.o        2) bkit-adore.o        3) cleaner.o        4) flkm.o        5) knark.o        6) modhide.o        7) mod_klgr.o        8) phide_mod.o        9) vlogger.o        10) p2.ko        11) rpldev.o        12) xC.o        13) strings.o        14) wkmr26.ko     */    do_system_check_initialisation     SOL_PROC=0    SOLARISX=""    if [ $SUNOS -eq 1 ]; then          if [ -h "/proc/1/path/a.out" ]; then            SOLARISX=-X            test $HAVE_READLINK -eq 1 && SOL_PROC=1        fi    fi     BEGINTIME=0    ENDTIME=0    if [ -n "$SECONDS" ]; then        BEGINTIME=`echo $SECONDS | cut -d. -f1`    elif [ $BSDOS -eq 1 ]; then        BEGINTIME=`date +%s`    elif [ -n "${PERL_CMD}" ]; then        BEGINTIME=`${PERL_CMD} -e printf "%d\n", time;`    fi     if [ -n "${USE_SYSLOG}" ]; then        ${LOGGER_CMD} -t "${PROGRAM_NAME}" -p ${USE_SYSLOG} "Rootkit hunter check started (version ${PROGRAM_version})"    fi            /*      该函数用来检查一些系统二进制命令和系统库文件,确保这些文件没有被篡改。因为后面的各项检查都会用到这些命令和库      */    do_system_commands_checks    /*    该函数用来检查rootkit病毒和木马     */    do_rootkit_checks    /*    该函数用来检查网络相关的内容。    */    do_network_checks     /*     该函数用来扫描本地主机     */    do_local_host_checks     /*     该函数用来检查一些特定的应用程序     */    do_app_checks......

do_system_check_initialisation函数执行结束之后,代码逻辑来到了do_system_commands_checks,这个函数负责检查一些系统二进制命令和系统库文件,确保这些文件没有被篡改。因为后面的各项检查都会用到这些命令和库

do_system_commands_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        display --to LOG --type INFO --nl USER_DISABLED_TEST system_commands        return    fi    /*    1. strings_check    该函数是用来检查strings命令是否正常。    检查方法:依次用一些rootkit病毒的文件名或路径做参数调用strings命令,看其是否能正常输出        1) 如果能,则说明没问题        2) 如果不能,则说明strings命令可能被该rootkit病毒或木马篡改过,意图隐藏该rootkit病毒或木马    */    strings_check    /*    2. shared_libs_check    该函数用来检查系统的动态链接库文件是否正常。 检查方法:        1) 首先检查和预加载相关的三个环境变量:            1.1) LD_PRELOAD            1.2) LD_AOUT_PRELOAD            1.3) LD_ELF_PRELOAD        依次插入这三个环境变量到指定的动态库文件中,查看显示的结果是否在用户设置动态库白名单中,如果不在,则认为有危险        2) 检查/etc/ld.so.preload        检查方法同上        3) 检查LD_LIBRARY_PATH        在两种情况            3.1) export LD_LIBRARY_PATH            3.2) unset LD_LIBRARY_PATH        下分别用ldd命令去测试find、ps、strings、md5sum、ls、stat命令,并比较两种情况下的输出结果是否相同(忽略地址),如果不相同,则说明有危险    */    shared_libs_check    /*    3. file_properties_check    该函数用来检查系统命令文件的属性、hash值等,以确定这些系统命令是否被篡改过    */    file_properties_check    keypresspause    return}

do_system_commands_checks函数执行结束之后,代码逻辑来到了do_rootkit_checks,该函数用来检查rootkit病毒和木马

do_rootkit_checks() {     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        display --to LOG --type INFO --nl USER_DISABLED_TEST rootkits        return    fi    /*    该函数通过检查和已知rootkit病毒相关联的文件或目录或内核符号是否存在来确定该rootkit病毒是否存在(即还是判断对应文件、目录是否存在的思路)    该函数中定义了和各个rootkit病毒相关联的文件或目录或内核符号,并调用子函数来scanrootkit(真正检查的逻辑在这个函数里)来进行检查    */    rootkit_file_dir_checks    check_test known_rkts || check_test all && keypresspause    /*    该函数用来补充检查rootkit。依次调用如下子函数:    1. suckit_extra_checks    该函数用来专门检查suckit病毒,检查方法:        1) 查看/sbin/init文件有几个硬链接,如果硬链接数大于1,则有可能存在suckit病毒。        2) 查看以xrk和mem为后缀的文件是否被隐藏。方法是:            2.1) 分别新建两个以xrk和mem为后缀的临时文件,然后查看其是否存在            2.2) 如果不存在,则说明该文件被隐藏了,可能存在suckit病毒        3) 测试skdet命令是否存在,如果存在,则对该命令进行一些测试,根据其结果判断是否存在suckit病毒        2. possible_rootkit_file_dir_checks     该函数用来检查一些特定的rootkit是否存在。检查方法是:        1) 通过检查某个文件或目录是否存在来判断对应的rootkit病毒是否存在。使用的数据(存在变量FILESCAN中)格式例如:        file:/dev/sdr0:T0rn Rootkit MD5 hash database             1.1) file表示后面的字段是一个文件            1.2) /dev/sdr0就是要搜索的文件            1.3) 后面的字段是rootkit病毒的描述        dir:/dev/ptyas:Langsuir installation directory             1.1) dir表示后面的字段是一个目录            1.2) /dev/ptyas就是要搜索的目录     3. possible_rootkit_string_checks    该函数用来检查某个二进制系统命令或启动文件总是否存在某个字符串,如存在则有危险 ,使用的数据(存在变量STRINGSCAN中)格式例如:         1) crond:LOGNAME=root:Illogic Rootkit            1.1) crond是二进制命令的文件名            1.2) LOGNAME=root是要搜索的字符串            1.3) Illogic Rootkit是rootkit病毒的描述        2) rcfile:in.inetd:SHV4 Rootkit            2.1) rcfile表示要在启动文件中去搜索            2.2) in.inetd是要搜索的字符串            2.3) SHV4 Rootkit是rootkit病毒的描述        3) 默认要搜索的启动文件(定义在变量RCLOCATIONS中)包括如下文件和目录,用户也可通过配置文件自己指定要搜索的启动文件和目录(定义STARTUP_PATHS字段)            3.1) RCLOCATIONS=/etc/rc.d /etc/rc.local            3.2) /usr/local/etc/rc.d            3.3) /usr/local/etc/rc.local            3.4) /etc/conf.d/local.start            3.5) /etc/init.d            3.6) /etc/inittab        上面路径有些是目录,表示该目录下(递归包含子目录)所有的"普通文件"(且不为符号链接)都要进行搜索    */    additional_rootkit_checks    /*    该函数用来检查malware病毒    */    malware_checks    /*    该函数用来检查木马。会依次进行以下检查:    1. 检查/etc/inetd.conf文件    2. 检查/etc/xinetd.conf文件    3. 检查apache后门模块。方法是:        1) 查看mod_rootme.so和mod_rootme2.so两个文件是否存在        2) 若存在,查看httpd.conf文件中是否有mod_rootme2.so字符串存在,若存在则说明有问题    */    trojan_checks    /*    该函数用来检查和操作系统相关的项目,对于linux系统来说,这里调用linux_specific_checks函数进行检查。依次调用如下函数进行检查:    1. linux_loaded_modules    该函数用来检查当前加载的内核模块。方法是:        1) 测试lsmod命令的结果和/proc/modules文件中的内容是否一致,如果不一致则说明有危险,存在隐藏LKM的rootkit    2. inux_avail_modules    该函数用来检查系统中是否存有已知的危险模块。方法是:        1) 搜索/lib/modules/`uname -r 2>/dev/null`(这个目录也可由用户在配置文件中指定)目录中是否存在已知的危险模块。危险模块的名称存放在LKM_BADNAMES变量中,内容如下:            1.1) LKM_BADNAMES=adore.o            1.2) bkit-adore.o            1.3) cleaner.o            1.4) flkm.o            1.5) knark.o            1.6) modhide.o            1.7) mod_klgr.o            1.8) phide_mod.o            1.9) vlogger.o            1.10) p2.ko            1.11) rpldev.o            1.12) xC.o            1.13) strings.o            1.14) wkmr26.ko    */    os_specific_checks    keypresspause    return}

结束了do_rootkit_checks,代码逻辑来到do_network_checks,do_network_checks负责检查网络相关的内容

do_network_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        display --to LOG --type INFO --nl USER_DISABLED_TEST network        return    fi    /*    do_network_port_checks    该函数用来检查网络端口,扫描是否有已知的后门端口被使用。 检查原理是: 在数据库文件backdoorports.dat中存放有多条后门端口的记录,格式如下:    1) <port>:<description>:protocol        1.1) port表示端口号,其值在1-65535之间        1.2) description是后门木马的描述        1.3) protocol是协议类型,为TCP或者UDP    2) 实例:        1984:Fuckit Rootkit:TCP:    该条记录表示Fuckit Rootkit这个rootkit病毒以TCP协议的方式使用了1984端口    真正的检查工作是在函数check_port_wl中完成的        1) 程序从backdoorports.dat中依次读出每条记录,解析出端口和协议        2) 用lsof命令来搜索以该协议方式使用该端口的进程(lsof -wnlP -i TCP:1984)并拿到其PID        3) 根据这个PID得到进程名称        4) 如果lsof命令没有搜索到以该协议方式使用该端口的进程或该端口在用户设置的白名单中,就说明没有危险,否则有危险    */    do_network_port_checks    /*    该函数用来扫描隐藏端口。扫描时需要使用unhide-tcp命令     */    do_network_hidden_port_checks    /*    该函数用来扫描是否有网络接口处于混杂模式和是否有抓包应用程序。    检查混杂模式的方法:    1. 查看下面两个命令的输出结果:        1) ifconfig 2>&1 | awk ‘BEGIN { RS="" }; /PROMISC/ { print }‘        2) ip link | grep ‘^[0-9]‘ | grep -vE "^[0-9][0-9]*: (${IFWLIST}):" | grep ‘PROMISC‘            2.1) 其中IFWLIST变量存放的是白名单网络接口    如果上述两个命令的输出为空,则说明没有处于混杂模式的网络接口,否则存在处于混杂模式的网路接口    2. 检查抓包程序的方法:        1) 先运行命令egrep -v ‘^sk|888e‘ /proc/net/packet | awk ‘{ print $9 }‘得到一个inode列表,将其存放在变量INODE_LIST中。        2) 然后用命令lsof -lMnPw -d 1-20 | egrep "[ ](${INODE\_LIST})[ ]" | awk ‘{ print $2 }‘得到各个inode对应的PID        3) 并利用/proc/$PID/exe或/proc/$PID/status文件得到进程名称。        4) 如果得到的进程名称没有在白名单列表中,则说明该进程就是抓包软件    */    do_network_interface_checks    return}

结束了do_network_checks,代码逻辑来到了do_local_host_checks,do_local_host_checks负责扫描本地主机

do_local_host_checks() {     /*     该函数用来扫描本地主机     */    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        display --to LOG --type INFO --nl USER_DISABLED_TEST local_host        return    fi     /*    该函数用来检查系统启动文件      1. 检查主机名:        1) 先用hostname命令查看主机名        2) 如果为空则用uname -n命令查看主机名        3) 如果仍为空,说明有问题。        2. 检查系统启动文件:         1) 检查方法是在系统启动文件中搜索特定的字符串,如果搜到,则说明有危险        2) 要搜索的字符串存放在变量RCLOCAL_STRINGS中,格式形如:        /usr/bin/rpc.wall:Linux Rootkit (LRK4)            2.1) /usr/bin/rpc.wall就是要搜索的字符串            2.2) Linux Rootkit (LRK4)是对应的rootkit病毒说明    */    do_system_startup_file_checks     /*     该函数用来检查系统帐户和组    1. 先检查/etc/passwd文件是否存在且为非空白文件,如果不存在或为空则告警。    2. 找出/etc/passwd文件中uid为0(即拥有root权限)的所有帐户的帐户名(用命令grep ‘^[^:]*:[^:]*:0:‘ /etc/passwd | cut -d: -f1),如果这些帐户名不在用户设置的白名单中(root默认在白名单中),则说明存在
危险 3. 检查所有的无密码帐户,分为两步: 1) 首先在shadow文件(/etc/shadow及tcb相关文件)中搜索空密码帐户:grep ‘^[^:]*::‘ ${SHADOW\_FILE} | cut -d: -f1 2) 然后在/etc/passwd文件中搜索空密码帐户:grep ‘^[^:]*::‘ /etc/passwd | cut -d: -f1 这两步中得到的结果,要忽略帐户名为"+"的帐户(这个和NIS/YP有关)并要进行白名单检查。如果仍然有空密码帐户,则有危险,需要告警。 4. 检查自从上次运行rkhunter以来,/etc/passwd的内容文件有没有变化 rkhunter脚本在运行后会在一个临时目录中保存当前系统的/etc/passwd文件。进行该项检查时,用diff命令来比较上次保存的passwd文件和系统当前的/etc/passwd文件,如果有变化则告警。 5. 检查自从上次运行rkhunter以来,/etc/gourp的内容文件有没有变化 6. 检查root帐户的shell的history 依次检查 1) /root/.bash_history(bash) 2) /root/.sh_history(Korn) 3) /root/.history(C-shell) 4) /root/.zhistory(zsh) 四个文件是否存在,并且是否为符号链接文件,如果是则存在危险
*/ do_group_accounts_check /* 该函数用来检查某些系统软件的配置文件。当前检查的配置文件包括SSH和syslog 1. 在/etc、/etc/ssh、/usr/local/etc、/usr/local/etc/ssh目录寻找SSH的配置文件sshd_config 2. 查看sshd是否允许root用户用SSH登陆(sshd_config文件中PermitRootLogin字段)。看其和rkhunter配置文件中用户的设置(ALLOW_SSH_ROOT_USER字段)是否相同,不相同则告警。如果ALLOW_SSH_ROOT_USER字段没
有被设置,则rkhunter默认不允许root用户用SSH登陆。注意:sshd本身默认是允许root用户登陆的 3. 查看sshd的协议版本是否为1(sshd_config文件中Protocol字段),若为1则告警 4. 查看syslog守护程序是否在运行 1) 运行命令ps ax | egrep ‘(syslogd|syslog-ng)( |$)‘ | grep -v ‘egrep‘ 2) 若结果为空,运行命令ps ax | egrep ‘metalog( |$)‘ | grep -v ‘egrep‘ 3) 若结果为空,运行命令ps ax | egrep ‘socklog( |$)‘ | grep -v ‘egrep‘ 4) 若结果为空,则告警。 5. 检查syslog的配置文件是否允许远程日志
*/ do_system_config_files_check /* 该函数用来检查文件系统的可疑文件 */ do_filesystem_check keypresspause return}

结束了do_local_host_checks之后,代码逻辑来到do_app_checks,do_app_checks负责检查一些特定的应用程序

do_app_checks() {     if `check_test apps`; then        display --to LOG --type INFO --screen-nl --nl STARTING_TEST apps    else        display --to LOG --type INFO --nl USER_DISABLED_TEST apps        return    fi     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    /*     该函数用来检查一些特定的应用程序    本函数会用到一个数据库文件:programs_bad.dat    在这个文件中存放着多个已知的有BUG的应用程序的名称及其对应的版本号 ,本函数要检查的应用程序名称存放在变量APP_NAMES中,其定义如下:    APP_NAMES=    exim:Exim MTA    gpg:GnuPG    httpd:Apache    named:Bind DNS    openssl:OpenSSL    php:PHP    procmail:Procmail MTA    proftpd:ProFTPD    sshd:OpenSSH    其中冒号前面是应用程序的名称,冒号后面是描述信息    本函数会用到的白名单:在rkhunter的配置文件/etc/rkhunter.conf中    字段APP_WHITELIST存放着用户指定的应用程序白名单。    检查步骤:    1. 用find命令找出APP_NAMES中包含的应用程序的全路径。    2. 用各个应用程序得到其对应的版本号。    3. 依次查看各个应用程序是否在白名单中,如果不在,则进行下一步检查。    4. 依次在programs_bad.dat中搜索上述各个应用程序及其对应的版本号,如果搜到了,则说明该版本程序有问题,需要向用户告警。     */    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         APPS_COUNT=`expr ${APPS_COUNT} + 1`        VERSION=""        WHOLE_VERSION=""                 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 { print $3 }`                ;;            gpg)                WHOLE_VERSION=`${APP_CMD_FOUND} --version --homedir / 2>/dev/null`                VERSION=`echo "${WHOLE_VERSION}" | grep GnuPG | awk { 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}" | egrep ^(named|BIND)[     ][     ]*[0-9] | grep -v / | awk { 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 { 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 { print $2 } | cut -d- -f1`                ;;            procmail)                WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>&1`                VERSION=`echo "${WHOLE_VERSION}" | grep ^procmail[     ][     ]*v[0-9] | awk { 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 { 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 "`egrep -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                display --to LOG --type INFO APPS_NOT_FOUND "${APPLICATION}"            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}"                    display --to LOG --type INFO APPS_CHECK_WL "${APPLICATION}"                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}"                    display --to LOG --type INFO APPS_CHECK_VERSION_WL "${APPLICATION}" "${VERSION}"                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}"                    display --to LOG --type INFO APPS_CHECK_VERSION_FOUND "${APPLICATION}" "${VERSION}"                fi            fi        done        IFS=$RKHIFS    fi    display --to LOG --type INFO APPS_TOTAL_COUNT $APPS_COUNT $APPS_TOTAL_COUNT    return}

结束了do_app_checks之后,rkhunter的主代码逻辑基本结束,接下来就是显示检测结果的时候
Relevant Link:

http://blog.chinaunix.net/uid-26526735-id-3938319.html

 

Copyright (c) 2014 LittleHann All rights reserved