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 8cc5af401f524b6fb3f12e047ca0ed89657d2183
parent e994b529536c363b7718be1cb3db109b7f003df7
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date:   Thu,  4 Feb 2021 17:31:37 +0100

Add freeing logic

Diffstat:
Mproject/extract_sizeret.py | 36++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+), 0 deletions(-)

diff --git a/project/extract_sizeret.py b/project/extract_sizeret.py @@ -11,6 +11,11 @@ break_arg = { "__kmalloc": "rdi", } +free_funcs = { + "kfree": "rdi", + "kmem_cache_free" : "rsi" +} + entries = set() exits = set() types = {} @@ -27,6 +32,9 @@ class PrintMem(gdb.Command): def invoke(self, arg, from_tty): global mem_map + if not mem_map: + return None + for addr, (type, size, caller) in mem_map.items(): print(f"type: {type}, size: {size}, addr: {hex(addr)}, caller: {caller}") @@ -98,6 +106,30 @@ class EntryExitBreakpoint(gdb.Breakpoint): return None +class FreeBreakpoint(gdb.Breakpoint): + def __init__(self, b): + gdb.Breakpoint.__init__(self, b) + + def stop(self): + global mem_map + global free_funcs + + frame = gdb.newest_frame() + + if not frame.is_valid(): + return False + + x = int(frame.read_register(free_funcs[frame.name()])) & (2 ** 64 - 1) + + if x is None: + return False + + if x in mem_map: + print("Freeing ", mem_map[x]) + mem_map.pop(x) + + return False + class Stage3(): breakpoints = [] @@ -130,4 +162,8 @@ class Stage3(): self.breakpoints.append(b_exit) exits.add(b_exit.number) + for f in free_funcs: + FreeBreakpoint(f) + + Stage3()