X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Frootcheck%2Fcheck_rc_pids.c;h=7c1c6452659c84d14d6b3c960af51ae956fa090e;hp=bd06f2d66904e97932b60c43fe98014783d3c61e;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/rootcheck/check_rc_pids.c b/src/rootcheck/check_rc_pids.c old mode 100755 new mode 100644 index bd06f2d..7c1c645 --- a/src/rootcheck/check_rc_pids.c +++ b/src/rootcheck/check_rc_pids.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/rootcheck/check_rc_pids.c, 2011/09/08 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -14,87 +11,82 @@ #include "shared.h" #include "rootcheck.h" +/* Prototypes */ +static int proc_read(int pid); +static int proc_chdir(int pid); +static int proc_stat(int pid); +static void loop_all_pids(const char *ps, pid_t max_pid, int *_errors, int *_total); -int noproc; +/* Global variables */ +static int noproc; -/** int proc_read(int pid) - * If /proc is mounted, check to see if the pid is present - */ -int proc_read(int pid) +/* If /proc is mounted, check to see if the pid is present */ +static int proc_read(int pid) { - char dir[OS_SIZE_1024 +1]; + char dir[OS_SIZE_1024 + 1]; - if(noproc) - return(0); + if (noproc) { + return (0); + } snprintf(dir, OS_SIZE_1024, "%d", pid); - if(isfile_ondir(dir, "/proc")) - { - return(1); + if (isfile_ondir(dir, "/proc")) { + return (1); } - return(0); + return (0); } - -/** int proc_chdir(int pid) - * If /proc is mounted, check to see if the pid is present - */ -int proc_chdir(int pid) +/* If /proc is mounted, check to see if the pid is present */ +static int proc_chdir(int pid) { int ret = 0; char curr_dir[OS_SIZE_1024 + 1]; char dir[OS_SIZE_1024 + 1]; - if(noproc) - return(0); - - if(!getcwd(curr_dir, OS_SIZE_1024)) - { - return(0); + if (noproc) { + return (0); + } + if (getcwd(curr_dir, OS_SIZE_1024) == NULL) { + return (0); + } + if (chdir("/proc") == -1) { + return (0); } - - if(chdir("/proc") == -1) - return(0); snprintf(dir, OS_SIZE_1024, "/proc/%d", pid); - if(chdir(dir) == 0) - { + if (chdir(dir) == 0) { ret = 1; } /* Returning to the previous directory */ - chdir(curr_dir); + if (chdir(curr_dir) == -1) { + return (0); + } - return(ret); + return (ret); } - -/** int proc_stat(int pid) - * If /proc is mounted, check to see if the pid is present there. - */ -int proc_stat(int pid) +/* If /proc is mounted, check to see if the pid is present there */ +static int proc_stat(int pid) { char proc_dir[OS_SIZE_1024 + 1]; - if(noproc) - return(0); + if (noproc) { + return (0); + } snprintf(proc_dir, OS_SIZE_1024, "%s/%d", "/proc", pid); - if(is_file(proc_dir)) - { - return(1); + if (is_file(proc_dir)) { + return (1); } - return(0); + return (0); } - -/** void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) - * Check all the available PIDs for hidden stuff. - */ -void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) +/* Check all the available PIDs for hidden stuff */ +static void loop_all_pids(const char *ps, pid_t max_pid, int *_errors, int *_total) { int _kill0 = 0; int _kill1 = 0; @@ -110,14 +102,14 @@ void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) pid_t i = 1; pid_t my_pid; - char command[OS_SIZE_1024 +1]; + char command[OS_SIZE_1024 + 1]; my_pid = getpid(); - for(;;i++) - { - if((i <= 0)||(i > max_pid)) + for (;; i++) { + if ((i <= 0) || (i > max_pid)) { break; + } (*_total)++; @@ -128,205 +120,157 @@ void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) _gpid0 = 0; _gpid1 = 0; _ps0 = -1; - _proc_stat = 0; - _proc_read = 0; - _proc_chdir = 0; - /* kill test */ - if(!((kill(i, 0) == -1)&&(errno == ESRCH))) - { + if (!((kill(i, 0) == -1) && (errno == ESRCH))) { _kill0 = 1; } - /* getsid to test */ - if(!((getsid(i) == -1)&&(errno == ESRCH))) - { + /* getsid test */ + if (!((getsid(i) == -1) && (errno == ESRCH))) { _gsid0 = 1; } /* getpgid test */ - if(!((getpgid(i) == -1)&&(errno == ESRCH))) - { + if (!((getpgid(i) == -1) && (errno == ESRCH))) { _gpid0 = 1; } - - /* proc stat */ + /* /proc test */ _proc_stat = proc_stat(i); - - /* proc readdir */ _proc_read = proc_read(i); - - /* proc chdir */ _proc_chdir = proc_chdir(i); - - /* IF PID does not exist, keep going */ - if(!_kill0 && !_gsid0 && !_gpid0 && - !_proc_stat && !_proc_read && !_proc_chdir) - { + /* If PID does not exist, move on */ + if (!_kill0 && !_gsid0 && !_gpid0 && + !_proc_stat && !_proc_read && !_proc_chdir) { continue; } - /* We do not need to look at our own pid */ - else if(i == my_pid) - { + /* Ignore our own pid */ + if (i == my_pid) { continue; } - /* Checking the number of errors */ - if((*_errors) > 15) - { - char op_msg[OS_SIZE_1024 +1]; - snprintf(op_msg,OS_SIZE_1024,"Excessive number of hidden processes" - ". It maybe a false-positive or " - "something really bad is going on."); + /* Check the number of errors */ + if ((*_errors) > 15) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Excessive number of hidden processes" + ". It maybe a false-positive or " + "something really bad is going on."); notify_rk(ALERT_SYSTEM_CRIT, op_msg); return; } - - /* checking if process appears on ps */ - if(*ps) - { - snprintf(command, OS_SIZE_1024, "%s -p %d > /dev/null 2>&1", - ps, - (int)i); - - /* Found PID on ps */ + /* Check if the process appears in ps(1) output */ + if (*ps) { + snprintf(command, OS_SIZE_1024, "%s -p %d > /dev/null 2>&1", ps, (int)i); _ps0 = 0; - if(system(command) == 0) + if (system(command) == 0) { _ps0 = 1; + } } - /* If we are being run by the ossec hids, sleep here (no rush) */ - #ifdef OSSECHIDS - sleep(2); - #endif + /* If we are run in the context of OSSEC-HIDS, sleep here (no rush) */ +#ifdef OSSECHIDS + debug1("%s: DEBUG: pause for %u", ARGV0, rootcheck.tsleep); + sleep(rootcheck.tsleep); +#endif - /* Everyone returned ok */ - if(_ps0 && _kill0 && _gsid0 && _gpid0 && _proc_stat && _proc_read) - { + /* Everything fine, move on */ + if (_ps0 && _kill0 && _gsid0 && _gpid0 && _proc_stat && _proc_read) { continue; } - - - /* If our kill or getsid system call, got the - * PID , but ps didn't, we need to find if it was a problem - * with a PID being deleted (not used anymore) + /* + * If our kill or getsid system call got the PID but ps(1) did not, + * find out if the PID is deleted (not used anymore) */ - { - if(!((getsid(i) == -1)&&(errno == ESRCH))) - { - _gsid1 = 1; - } - - if(!((kill(i, 0) == -1)&&(errno == ESRCH))) - { - _kill1 = 1; - } - - if(!((getpgid(i) == -1)&&(errno == ESRCH))) - { - _gpid1 = 1; - } - - - _proc_stat = proc_stat(i); - - _proc_read = proc_read(i); + if (!((getsid(i) == -1) && (errno == ESRCH))) { + _gsid1 = 1; + } + if (!((kill(i, 0) == -1) && (errno == ESRCH))) { + _kill1 = 1; + } + if (!((getpgid(i) == -1) && (errno == ESRCH))) { + _gpid1 = 1; + } - _proc_chdir = proc_chdir(i); + _proc_stat = proc_stat(i); + _proc_read = proc_read(i); + _proc_chdir = proc_chdir(i); - /* If it matches, process was terminated */ - if(!_gsid1 &&!_kill1 &&!_gpid1 &&!_proc_stat && - !_proc_read &&!_proc_chdir) - { - continue; - } + /* If it matches, process was terminated in the meantime, so move on */ + if (!_gsid1 && !_kill1 && !_gpid1 && !_proc_stat && + !_proc_read && !_proc_chdir) { + continue; } - #ifdef AIX - /* Ignoring AIX wait and sched programs. */ - if((_gsid0 == _gsid1) && - (_kill0 == _kill1) && - (_gpid0 == _gpid1) && - (_ps0 == 1) && - (_gsid0 == 1) && - (_kill0 == 0)) - { +#ifdef AIX + /* Ignore AIX wait and sched programs */ + if (_gsid0 == _gsid1 && + _kill0 == _kill1 && + _gpid0 == _gpid1 && + _ps0 == 1 && + _gsid0 == 1 && + _kill0 == 0) { /* The wait and sched programs do not respond to kill 0. - * So, if everything else finds it, including ps, getpid, getsid, - * but not - * kill, we can safely ignore on AIX. - * A malicious program would specially try to hide from ps.. + * So if everything else finds it, including ps, getpid, getsid, + * but not kill, we can safely ignore on AIX. + * A malicious program would specially try to hide from ps. */ continue; } - #endif - +#endif - if((_gsid0 == _gsid1)&& - (_kill0 == _kill1)&& - (_gsid0 != _kill0)) - { - /* If kill found, but getsid and getpgid didnt', it may + if (_gsid0 == _gsid1 && + _kill0 == _kill1 && + _gsid0 != _kill0) { + /* If kill worked, but getsid and getpgid did not, it may * be a defunct process -- ignore. */ - if(!((_kill0 == 1)&&(_gsid0 == 0)&&(_gpid0 == 0)&&(_gsid1 == 0))) - { - char op_msg[OS_SIZE_1024 +1]; + if (! (_kill0 == 1 && _gsid0 == 0 && _gpid0 == 0) ) { + char op_msg[OS_SIZE_1024 + 1]; snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " - "kill (%d) or getsid (%d). Possible kernel-level" - " rootkit.", (int)i, _kill0, _gsid0); - + "kill (%d) or getsid (%d). Possible kernel-level" + " rootkit.", (int)i, _kill0, _gsid0); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); (*_errors)++; } - } - else if((_kill1 != _gsid1)|| - (_gpid1 != _kill1)|| - (_gpid1 != _gsid1)) - { - /* See defunct process comment above. */ - if(!((_kill1 == 1)&&(_gsid1 == 0)&&(_gpid0 == 0)&&(_gsid1 == 0))) - { - char op_msg[OS_SIZE_1024 +1]; - snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " - "kill (%d), getsid (%d) or getpgid. Possible " - "kernel-level rootkit.", (int)i, _kill1, _gsid1); + } else if (_kill1 != _gsid1 || + _gpid1 != _kill1 || + _gpid1 != _gsid1) { + /* See defunct process comment above */ + if (! (_kill1 == 1 && _gsid0 == 0 && _gpid0 == 0 && _gsid1 == 0) ) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "kill (%d), getsid (%d) or getpgid. Possible " + "kernel-level rootkit.", (int)i, _kill1, _gsid1); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); (*_errors)++; } - } - else if((_proc_read != _proc_stat)|| - (_proc_read != _proc_chdir)|| - (_proc_stat != _kill1)) - { - /* checking if the pid is a thread (not showing on proc */ - if(!noproc && !check_rc_readproc((int)i)) - { - char op_msg[OS_SIZE_1024 +1]; + } else if (_proc_read != _proc_stat || + _proc_read != _proc_chdir || + _proc_stat != _kill1) { + /* Check if the pid is a thread (not showing in /proc */ + if (!noproc && !check_rc_readproc((int)i)) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " - "/proc. Possible kernel level rootkit.", (int)i); + "/proc. Possible kernel level rootkit.", (int)i); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); (*_errors)++; } - } - else if(_gsid1 && _kill1 && !_ps0) - { + } else if (_gsid1 && _kill1 && !_ps0) { /* checking if the pid is a thread (not showing on ps */ - if(!check_rc_readproc((int)i)) - { - char op_msg[OS_SIZE_1024 +1]; - snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " - "ps. Possible trojaned version installed.", - (int)i); + if (!check_rc_readproc((int)i)) { + char op_msg[OS_SIZE_1024 + 1]; + snprintf(op_msg, OS_SIZE_1024, "Process '%d' hidden from " + "ps. Possible trojaned version installed.", + (int)i); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); (*_errors)++; } @@ -334,59 +278,52 @@ void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) } } - -/* check_rc_sys: v0.1 - * Scan the whole filesystem looking for possible issues - */ +/* Scan the whole filesystem looking for possible issues */ void check_rc_pids() { int _total = 0; int _errors = 0; - char ps[OS_SIZE_1024 +1]; + char ps[OS_SIZE_1024 + 1]; char proc_0[] = "/proc"; char proc_1[] = "/proc/1"; pid_t max_pid = MAX_PID; - noproc = 1; /* Checking where ps is */ - memset(ps, '\0', OS_SIZE_1024 +1); + memset(ps, '\0', OS_SIZE_1024 + 1); strncpy(ps, "/bin/ps", OS_SIZE_1024); - if(!is_file(ps)) - { + if (!is_file(ps)) { strncpy(ps, "/usr/bin/ps", OS_SIZE_1024); - if(!is_file(ps)) + if (!is_file(ps)) { ps[0] = '\0'; + } } - /* Proc is mounted */ - if(is_file(proc_0) && is_file(proc_1)) - { + if (is_file(proc_0) && is_file(proc_1)) { noproc = 0; } loop_all_pids(ps, max_pid, &_errors, &_total); - if(_errors == 0) - { - char op_msg[OS_SIZE_1024 +1]; + if (_errors == 0) { + char op_msg[OS_SIZE_1024 + 1]; snprintf(op_msg, OS_SIZE_1024, "No hidden process by Kernel-level " - "rootkits.\n %s is not trojaned. " - "Analyzed %d processes.", ps, _total); + "rootkits.\n %s is not trojaned. " + "Analyzed %d processes.", ps, _total); notify_rk(ALERT_OK, op_msg); } return; } -/* EOF */ #else void check_rc_pids() { return; } #endif +