X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Frootcheck%2Fcheck_rc_pids.c;h=7c1c6452659c84d14d6b3c960af51ae956fa090e;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=a2868e33cf88516a6d1f9f27fbc1e90e3dcfb330;hpb=301048b51990573e58a30dc4a5bb4ec285cad554;p=ossec-hids.git diff --git a/src/rootcheck/check_rc_pids.c b/src/rootcheck/check_rc_pids.c old mode 100755 new mode 100644 index a2868e3..7c1c645 --- a/src/rootcheck/check_rc_pids.c +++ b/src/rootcheck/check_rc_pids.c @@ -1,5 +1,3 @@ -/* @(#) $Id$ */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -13,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); - - return(ret); -} + if (chdir(curr_dir) == -1) { + return (0); + } + 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; @@ -105,21 +98,21 @@ void loop_all_pids(char *ps, pid_t max_pid, int *_errors, int *_total) int _proc_stat = 0; int _proc_read = 0; int _proc_chdir = 0; - + 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)++; - + _kill0 = 0; _kill1 = 0; _gsid0 = 0; @@ -127,265 +120,210 @@ 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(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 - - /* Everyone returned ok */ - if(_ps0 && _kill0 && _gsid0 && _gpid0 && _proc_stat && _proc_read) - { + + /* 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 + + /* 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 (!((getsid(i) == -1) && (errno == ESRCH))) { + _gsid1 = 1; + } + if (!((kill(i, 0) == -1) && (errno == ESRCH))) { + _kill1 = 1; + } + if (!((getpgid(i) == -1) && (errno == ESRCH))) { + _gpid1 = 1; + } - if(!((getpgid(i) == -1)&&(errno == ESRCH))) - { - _gpid1 = 1; - } - - - _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; - } + _proc_stat = proc_stat(i); + _proc_read = proc_read(i); + _proc_chdir = proc_chdir(i); + + /* 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 - - - if((_gsid0 == _gsid1)&& - (_kill0 == _kill1)&& - (_gsid0 != _kill0)) - { - /* If kill found, but getsid and getpgid didnt', it may +#endif + + 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]; + 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); + "ps. Possible trojaned version installed.", + (int)i); + notify_rk(ALERT_ROOTKIT_FOUND, op_msg); (*_errors)++; } } } } - -/* 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 +