/* * Function called when loading the kernel module. * Prints a welcome-message and then does its magic. */ int init_module (void) { int ret; ROOTKIT_DEBUG("****************************************\n"); ROOTKIT_DEBUG("Beginning rootkit detection procedure...\n"); ROOTKIT_DEBUG("****************************************\n"); /* open the log file */ fd = filp_open(path, O_CREAT|O_WRONLY|O_APPEND|O_TRUNC, S_IRWXU); if(IS_ERR(fd)) { ROOTKIT_DEBUG("Error while trying to open the file '%s'! Terminating...\n", path); return -EIO; } /* check the sys call table */ ret = check_syscalls(); if(ret < 0) { ROOTKIT_DEBUG("Error while checking the system call table!\n"); return ret; } /* check the processes */ ret = check_processes(); if(ret < 0) { ROOTKIT_DEBUG("Error while checking the running processes!\n"); return ret; } ret = check_netfilter_hooks(); if(ret < 0) { ROOTKIT_DEBUG("Error while checking netfiler hooks!\n"); return ret; } ret = count_modules(); if(ret < 0) { ROOTKIT_DEBUG("Error while checking the loaded modules!\n"); return ret; } /* close the log file */ filp_close(fd, NULL); /* log the completion */ ROOTKIT_DEBUG("****************************************\n"); ROOTKIT_DEBUG("Check complete. You may now unload.\n"); ROOTKIT_DEBUG("****************************************\n"); return 0; }
/* execute test binary */ int check_bin(char *tbinary, time_t timeout) { pid_t child_pid; int result, res = 0; if (timeout > 0) res = check_processes(timeout); if (res == ETOOLONG) { #if USE_SYSLOG syslog(LOG_ERR, "test-binary %s exceeded time limit %ld", tbinary, timeout); #endif /* USE_SYSLOG */ return res; } child_pid = fork(); if (!child_pid) { /* child, exit immediately, if no test binary given */ if (tbinary == NULL) exit(0); /* Don't want the stdin and stdout of our test program * to cause trouble * So make stdout and stderr go to their respective files */ if (!freopen("/var/log/watchdog/test-bin.stdout", "a+", stdout)) exit (errno); if (!freopen("/var/log/watchdog/test-bin.stderr", "a+", stderr)) exit (errno); /* else start binary */ execl(tbinary, tbinary, NULL); /* execl should only return in case of an error */ /* so we return that error */ exit(errno); } else if (child_pid < 0) { /* fork failed */ int err = errno; if (errno == EAGAIN) { /* process table full */ #if USE_SYSLOG syslog(LOG_ERR, "process table is full!"); #endif /* USE_SYSLOG */ return (EREBOOT); } else if (softboot) return (err); else return (ENOERR); } else { int ret, err; /* fork was okay, add child to process list */ add_process(child_pid); /* wait for child(s) to stop */ /* but only after a short sleep */ sleep(tint >> 1); do { ret = waitpid(-1, &result, WNOHANG); err = errno; if (ret > 0) remove_process(ret); } while (ret > 0 && WIFEXITED(result) != 0 && WEXITSTATUS(result) == 0); /* check result: */ /* ret < 0 => error */ /* ret == 0 => no more child returned, however we may already have caught the actual child */ /* WIFEXITED(result) == 0 => child did not exit normally but was killed by signal which was not caught */ /* WEXITSTATUS(result) != 0 => child returned an error code */ if (ret > 0) { if (WIFEXITED(result) != 0) { /* if one of the scripts returns an error code just return that code */ #if USE_SYSLOG syslog(LOG_ERR, "test binary returned %d", WEXITSTATUS(result)); #endif /* USE_SYSLOG */ return (WEXITSTATUS(result)); } else if (WIFSIGNALED(result) != 0) { /* if one of the scripts was killed return ECHKILL */ #if USE_SYSLOG syslog(LOG_ERR, "test binary was killed by uncaught signal %d", WTERMSIG(result)); #endif /* USE_SYSLOG */ return (ECHKILL); } } else { /* in case there are still old childs running due to an error */ /* log that error */ if (err != 0 && err != ECHILD) { #if USE_SYSLOG errno = err; syslog(LOG_ERR, "child %d did not exit immediately (error = %d = '%m')", child_pid, err); #else /* USE_SYSLOG */ perror(progname); #endif /* USE_SYSLOG */ if (softboot) return (err); } } } return (ENOERR); }
int main(int /* argc */, char* /* argv */[]) { auto bg_tasks = std::map<int, bg_task>(); timeval start; gettimeofday(&start, nullptr); int next_task_id = 0; bool quit = false; while (not quit) { std::string line; std::cout << get_current_dir_name() << "> "; std::cout.flush(); if (not std::getline(std::cin, line) || line == "exit") { std::cout << std::endl; quit = true; } else { auto is_whitespace = [](char c){ return std::isspace(c) != 0; }; auto begin = std::find_if_not(line.begin(), line.end(), is_whitespace); auto end = line.end(); auto result = begin; std::vector<std::string> args; while (begin != end) { result = std::find(begin, end, ' '); args.emplace_back(begin, result); begin = std::find_if_not(result, end, is_whitespace); } if (not args.empty()) { if (args.back() == "&") { args.pop_back(); auto task = launch_background_cmd(next_task_id++, args); std::cout << task << std::endl; bg_tasks[task.exec_proc.id] = task; } else if (args[0] == "cd") { cd(args[1]); } else if (args[0] == "aptaches") { check_processes(bg_tasks); // for (std::map<int, bg_task>::const_iterator it=bg_tasks.begin(); it!=bg_tasks.end(); ++it) { for (auto pair : bg_tasks) { std::cout << pair.second << std::endl; } } else { wait_cmd(launch_cmd(args)); } } } } /* Kill everything in bg_tasks */ check_processes(bg_tasks); for (auto pair : bg_tasks) { kill(pair.second.exec_proc.id, SIGTERM); } }