Kernel Monarch
Kernel Monarch
Platform: CUSTOM | Category: Reverse | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: alternate_device_node_creation, dentry_name_bypass, ftrace_hook_analysis, kernel_module_symbol_analysis, rodata_string_extraction, syscall_hook_identification
Summary
Walkthrough of the CUSTOM Reverse Kernel Monarch. Task: reverse a Linux kernel rootkit (malware.ko) that uses ftrace to hook syscalls and filter /dev/kmsg output. Solution: identify dentry-based filename check in hook_read, bypass by creating alterna
Description
A kernel rootkit intercepts system calls to hide sensitive information. Your mission is to reversing the kernel module, understand its hooking mechanism, and reveal what's hidden.
A ZIP archive (password: hackthebox) contains malware.ko, a Linux kernel module (rootkit). A remote QEMU VM instance is provided via netcat where the rootkit is already loaded. The goal is to reverse-engineer the hooking mechanism and recover the hidden flag from kernel logs.
Analysis
File Identification
$ file malware.ko
malware.ko: ELF 64-bit LSB relocatable, x86-64, not stripped, with debug_info
The module targets kernel 5.10.0-41-amd64, authored by "matheuz". Being not stripped with debug_info makes static analysis straightforward.
Symbol Table Reconnaissance
Key symbols discovered via nm:
| Symbol | Role |
|---|---|
poop_init | init_module — rootkit entry point |
poop_exit | cleanup_module — rootkit cleanup |
hide | Self-hides module from lsmod/sysfs |
fh_install_hooks | Installs ftrace-based syscall hooks |
fh_remove_hooks | Removes hooks on unload |
fh_ftrace_thunk | ftrace callback that redirects execution |
hook_read | Filters content read from specific files |
hook_write | Protects ftrace control files from writes |
hook_syslog / hook_do_syslog | Blocks dmesg/syslog access |
| |
Decoy Flag
A fake flag exists in plaintext in .rodata: HTB{f4k3_fl4g_f0r_r3v3rs1ng_0nly} — this is a red herring to mislead reversers who rely solely on strings.
Ftrace-Based Hooking Mechanism
The rootkit uses ftrace (Linux kernel's function tracing framework) to hook 6 system calls:
| Original Syscall | Hook Function | Purpose |
|---|---|---|
__x64_sys_read | hook_read | Filters lines from read output |
__x64_sys_write | hook_write | Blocks writes to ftrace control files |
__x64_sys_syslog | hook_syslog | Returns -1, blocks dmesg |
__ia32_sys_syslog | hook_ia32_syslog | Returns -1, blocks dmesg (32-bit compat) |
__ia32_sys_write | hook_ia32_write | Blocks writes to ftrace (32-bit compat) |
do_syslog | hook_do_syslog | Returns -1, blocks syslog internally |
| |
hook_read — The Core Filtering Logic
This is the most important hook and the one that hides the flag:
- File identification: Gets the file descriptor via
fget(), extracts the filename fromfile->f_path.dentry->d_name.name - Filename check: Compares against a whitelist of monitored files:
kmsg,kallsyms,enabled_functions,touched_functions - If filename matches: Calls the original
sys_read, then copies the buffer from userspace to kernel space - Line-by-line filtering: Splits output on
\ndelimiters, then for each line callsstrstr(line, "taint")andstrstr(line, "malware") - Censorship: Lines containing either keyword are dropped entirely; clean lines are reassembled and copied back to userspace
- If filename doesn't match: Passes through to original
sys_readunmodified
hook_write — Ftrace Self-Protection
- Checks if the target filename matches
ftrace_enabled(15 bytes) ortracing_on(11 bytes) - If matched: silently intercepts the write, preventing anyone from disabling ftrace (which would break all hooks)
- Otherwise: passes through to original write syscall
hook_syslog / hook_do_syslog — Complete Log Blockade
Both hooks simply return -1, completely blocking dmesg and any syslog-based kernel log access. This is a blunt but effective defense layer.
Module Self-Hiding
The hide() function, called during poop_init:
- Uses
kobject_delto remove the module from sysfs (invisible tolsmod) - Sets magic value
0xDEAD000000000100in module list pointers - The
/initscript also deletesmalware.kofrom disk after loading
Remote VM Environment
The QEMU VM's /init script reveals the loading sequence:
sh read-only • copy allowedecho 1 > /proc/sys/kernel/printk # suppress console output insmod /lib/modules/malware.ko # load rootkit rm -f /lib/modules/malware.ko # delete module file from disk setsid /bin/busybox cttyhack /bin/sh # drop to interactive shell
Solution
The Vulnerability: Dentry-Based Filename Check
The critical weakness in hook_read is that it checks the dentry filename (the name of the file as it appears in the directory entry) of the opened file descriptor. It does NOT check the device major:minor numbers or inode.
/dev/kmsg is a character device with major 1, minor 11. The hook filters reads from any file named kmsg — but if we create a new device node pointing to the same device with a different name, the filename check fails to match, and the read passes through completely unfiltered.
The Bypass
bash read-only • copy allowed# Create alternate device node for /dev/kmsg (char device major 1, minor 11) mknod /tmp/mylog c 1 11 # Read kernel messages through the unfiltered path cat /tmp/mylog
Since the filename is "mylog" (not "kmsg"), hook_read's strcmp against the monitored filenames returns false, and the original sys_read result is returned without any line filtering.
Revealed Output
The unfiltered kernel log shows three lines that were previously hidden (they contain "malware" and/or "taint"):
4,350,...,-;malware: loading out-of-tree module taints kernel.
5,351,...,-;malware: module verification failed: signature and/or required key missing - tainting kernel
6,352,...,-;HTB{REDACTED}
Line 352 contains the real flag, printed by the rootkit module during initialization via printk.
Key Takeaways / Lessons
- Mastering alternate_device_node_creation, dentry_name_bypass, ftrace_hook_analysis, kernel_module_symbol_analysis, rodata_string_extraction, syscall_hook_identification was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-05-11 • CUSTOM • Kernel Monarch • Difficulty: Medium