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 3760001ffbf3e97b9ee5c4a4d51206e5e3213b3b
parent bd068bd6667c8f1b930059eb61731b6269da0312
Author: deurzen <m.deurzen@tum.de>
Date:   Wed,  3 Feb 2021 22:55:21 +0100

Merge branch 'master' of github.com:deurzen/rootkit-programming-dev

Diffstat:
Mproject/extract_sizeret.py | 19++++++++++++-------
Mproject/occ.sh | 27---------------------------
2 files changed, 12 insertions(+), 34 deletions(-)

diff --git a/project/extract_sizeret.py b/project/extract_sizeret.py @@ -24,8 +24,9 @@ class PrintMem(gdb.Command): def __init__(self): super(PrintMem, self).__init__("print-mem", gdb.COMMAND_DATA) - def invoke(self, arg): + def invoke(self, arg, from_tty): global mem_map + print(mem_map) PrintMem() @@ -48,10 +49,12 @@ class EntryExitBreakpoint(gdb.Breakpoint): if t is None: return False - self.extract(f) - - print(t, prev_entry) + retval = self.extract(f) + if retval is None: + return False + + mem_map.add((t[0], retval[0], retval[1], t[1])) return False def extract(self, frame): @@ -64,10 +67,12 @@ class EntryExitBreakpoint(gdb.Breakpoint): # extract size from correct register if int(frame.read_register(break_arg[frame.name()])) > 0: prev_entry = f"size={frame.read_register(break_arg[frame.name()])}" + return None elif self.number in exits and prev_entry is not None: # extract return value, print for now - print(f"{prev_entry}, ret={hex(int(str(frame.read_register('rax')), 10) & (2 ** 64 - 1))}", flush=True) + ret = (prev_entry, (hex(int(str(frame.read_register('rax')), 10) & (2 ** 64 - 1)))) prev_entry = None + return ret def type_lookup(self, frame): global types @@ -84,7 +89,7 @@ class EntryExitBreakpoint(gdb.Breakpoint): key = f"{symtab.filename}:{sym.line}" if key in types: - return types[key] + return (types[key], key) f_iter = f_iter.older() @@ -114,7 +119,7 @@ class Stage3(): disass = gdb.execute(f"disass {b}", to_string=True).strip().split("\n") disass = [instr.split("\t") for instr in disass] instrs = [(instr[0].strip(), instr[1].split(" ")[0].strip()) for instr in disass if len(instr) > 1] - retqs = [int(loc.split("<")[1].split(">")[0]) for (loc, instr) in instrs if instr == "retq"] + retqs = [int(loc.split("<")[1].split(">")[0]) for (loc, instr) in instrs if instr == "ret" or instr == "retq"] # set breakpoints at function exits (retq), to extract return value for retq in retqs: diff --git a/project/occ.sh b/project/occ.sh @@ -21,33 +21,6 @@ fi echo "Generating file cscope.files.." find $1 \ - -path "$1arch/alpha*" -prune -o \ - -path "$1arch/arc*" -prune -o \ - -path "$1arch/arm*" -prune -o \ - -path "$1arch/arm64*" -prune -o \ - -path "$1arch/c6x*" -prune -o \ - -path "$1arch/h8300*" -prune -o \ - -path "$1arch/hexagon*" -prune -o \ - -path "$1arch/ia64*" -prune -o \ - -path "$1arch/m68k*" -prune -o \ - -path "$1arch/microblaze*" -prune -o \ - -path "$1arch/mips*" -prune -o \ - -path "$1arch/nds32*" -prune -o \ - -path "$1arch/nios2*" -prune -o \ - -path "$1arch/openrisc*" -prune -o \ - -path "$1arch/parisc*" -prune -o \ - -path "$1arch/powerpc*" -prune -o \ - -path "$1arch/riscv*" -prune -o \ - -path "$1arch/s390*" -prune -o \ - -path "$1arch/sh*" -prune -o \ - -path "$1arch/sparc*" -prune -o \ - -path "$1arch/um*" -prune -o \ - -path "$1arch/unicore32*" -prune -o \ - -path "$1arch/xtensa*" -prune -o \ - -path "$1drivers*" -prune -o \ - -path "$1Documentation*" -prune -o \ - -path "$1scripts*" -prune -o \ - -path "$1tools*" -prune -o \ -name "*.[chxsS]" -print > ./cscope.files echo "Done!"