Created
May 25, 2019 08:38
-
-
Save mpurzynski/445007783bbb251d924b797ae5cdb355 to your computer and use it in GitHub Desktop.
Some quick hack for a naive (but working) userspace rootkit detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <dlfcn.h> | |
#include <fcntl.h> | |
#define LIBC "/lib/x86_64-linux-gnu/libc.so.6" | |
#define PCAP "/usr/lib/x86_64-linux-gnu/libpcap.so" | |
#define PAM "/usr/lib64/libpam.so" | |
int main(int argc, char *argv[]) { | |
FILE * fp; | |
int bytes; | |
char * smapsl; | |
Dl_info dlInfo_libc, dlInfo_next; | |
static FILE *(*old_fopen) (const char *filename, const char *mode); | |
void *libc = dlopen(LIBC, RTLD_LAZY); // Directly open the libc ".so" | |
void *pcap = dlopen(PCAP, RTLD_LAZY); // Directly open the pcap ".so" | |
void *pam = dlopen(PAM, RTLD_LAZY); // Directly open the PAM ".so" | |
char *syscalls[] = {"open", "readdir", "readdir64", "fopen", "accept", "access", "link", "unlink", "read", "write", "rmdir", "stat", "stat64", "lstat", "lstat64", "__lxstat", "__lxstat64", "xstat", "xstat64", "unlink", "unlinkat", "opendir", "execve", "accept"}; | |
uint32_t i; | |
// Pointers to functions, to be filled when resolving | |
void *(*libc_func)(); | |
void *(*pcap_func)(); | |
void *(*pam_func)(); | |
void *(*next_func)(); | |
for (i = 0; i < 24; ++i) { | |
printf("[+] Checking %s syscall.\n", syscalls[i]); | |
// Straight outta libc | |
next_func = dlsym(RTLD_NEXT, syscalls[i]); | |
libc_func = dlsym(libc, syscalls[i]); | |
dladdr(next_func, &dlInfo_next); | |
dladdr(libc_func, &dlInfo_libc); | |
// Resolve symbols from the default library search order (thus infected by LD_PRELOAD) | |
printf("Libc address: %p\n", libc_func); | |
printf("Found in %s\n", dlInfo_libc.dli_fname); | |
printf("Next address: %p\n", next_func); | |
printf("Found in %s\n", dlInfo_next.dli_fname); | |
if (libc_func != next_func) { | |
printf("[!] Preload hooks dectected!\n"); | |
printf("Libc address: %p\n", libc_func); | |
printf("Next address: %p\n", next_func); | |
} | |
} | |
printf("[+] Checking if pcap_loop is hooked.\n"); | |
// Same dance as before | |
pcap_func = dlsym(pcap, "pcap_loop"); | |
next_func = dlsym(RTLD_NEXT, "pcap_loop"); | |
if (pcap_func != next_func) { | |
printf("[!] Preload hooks dectected!\n"); | |
printf("Pcap address: %p\n", pcap_func); | |
printf("Next address: %p\n", next_func); | |
} | |
// Azzazello!! | |
printf("[+] Checking if PAM is hooked.\n"); | |
// Same dance, once again | |
pam_func = dlsym(pam, "pam_authenticate"); | |
next_func = dlsym(RTLD_NEXT, "pam_authenticate"); | |
if (pam_func != next_func) { | |
printf("[!] Preload hooks dectected!\n"); | |
printf("PAM address: %p\n", pam_func); | |
printf("Next address: %p\n", next_func); | |
} | |
old_fopen = dlsym(libc, "fopen"); | |
fp = old_fopen("/proc/self/smaps", "r"); | |
smapsl = malloc(1024); | |
while (bytes = fread(smapsl, 1, sizeof(smapsl), fp)) { | |
fwrite(smapsl, 1, bytes, stdout); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment