#include #include #include #include #include #include #include /* * EnyeLKM GID checker. * EnyeLKM uses a special GID to know which processes to hide. This program brute forces its way through all GID's (takes hours) and will report when it finds the one that hides a process. This program needs to be run with root privileges to be effective since it needs to change its own GID. * To just perform a quick check on a couple of known GID's that your hackers have used, set the decimal GID's in the environment variable ENYEGIDS (colon separated). * Not that its especially important when looking for a kernel mode rootkit, but statically compiling this is probably a good idea... * Copyright 2008 Jacob Williams, williamsworx.com * Licensed under GPLv3. * If you find this useful (you know who you are), man up and buy me a beer (or a book, I'm a geek) */ gid_t def = 1217500843; // The default SGID for Enye 1.12, 1.14, and 1.2 char pidName[7]; gid_t curGid = 0; //arguably this shouldn't be global, but I figured over potentially 4 billion calls saved passing this onto the stack for potential debug... int pidThere() { DIR * proc; struct dirent * fname; int foundPid = 0; if (!(proc = opendir("/proc"))) { printf("Couldn't opendir on /proc at gid = %d\n", curGid); exit(-1); } errno = 0; while ((fname = readdir(proc))) { if (strcmp(fname->d_name, pidName) == 0) { foundPid = 1; } errno = 0; } if (errno) { perror("Reading directory in GID walk"); exit(-1); } closedir(proc); return foundPid; } void foundit() { printf("Success: our pid is missing from /proc with magic GID %d\nEnyeLKM likely running on this machine.\n", curGid); exit(0); } int main(int argc, char *argv[]) { pid_t pid; char * enyeGids; char *token, *copy; pid = getpid(); sprintf(pidName, "%d", pid); if (!pidThere) { printf("Could not find our PID in /proc with GID of zero. Something must be wrong.\nExiting...\n"); return 1; } curGid = def; if ((setregid(curGid, -1)) < 0) { printf("Couldn't set real GID to %d\n", curGid); exit(-1); } if (!pidThere()) { foundit(); } curGid = 0; enyeGids = getenv("ENYEGIDS"); if (enyeGids != NULL) { copy = (char *) malloc(strlen(enyeGids) + 1); if (copy == NULL) { printf("Could not allocate memory.\n"); exit(-1); } strcpy(copy, enyeGids); token = strtok(copy, ":"); while (token) { curGid = atoi(token); if ((setregid(curGid, -1)) < 0) { printf("Couldn't set real GID to %d\n", curGid); exit(-1); } if (!pidThere()) { foundit(); } token = strtok(0, ":"); } } curGid++; while (curGid != 0) { // When we get back to zero, we've tried them all (hours and hours) if ((setregid(curGid, -1)) < 0) { printf("Couldn't set real GID to %d\n", curGid); exit(-1); } if (!pidThere()) { foundit(); } curGid++; } printf("We've checked all possible GID's and our pid is still there.\nDoesn't look like Enye is running on this system.\n"); return 1; }