> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-14/linux-exploit/trick-0194/privilege-escalation-linux-exploit-kernel-exploit.md).

# Kernel Exploit

## Kernel Module Analysis (Root Trigger)

Use Ghidra to analyze the kernel module binary (`.ko`). Open the file:

```bash
ghidra /path/to/venom.ko
```

Once the binary is loaded, Ghidra performs an initial analysis. The CodeBrowser window is the primary interface for exploring the binary. Within the CodeBrowser, the Listing view displays the disassembled code, showing individual instructions like `cmp`. The Decompiler view shows the decompiled C-like code, which is incredibly useful for understanding the program's logic without having to read assembly. In the Decompiler view, you can often see `if` statements, loops, and function calls.

Inside Ghidra, examine functions that handle signals or potential backdoor triggers (e.g., `hacked_kill`). Look for the specific signal number that is checked (`cmp` instruction in assembly, or an `if` condition in decompiled code) immediately before the function responsible for privilege escalation (e.g., `give_root()`) is called. This reveals the non-standard signal needed to activate the root trigger.

Kernel modules can implement signal handling logic. For example, a thread within the module might check for pending signals using constructs similar to this C code snippet:

```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/syscalls.h>
#include <linux/kthread.h>

static struct task_struct *my_kthread = NULL;

static int signal_handler(void *data)
{
    allow_signal(SIGKILL); // Or other signals you want to catch

    while (!kthread_should_stop()) {
        set_current_state(TASK_INTERRUPTIBLE);
        schedule();
        if (signal_pending(current)) {
            // Handle the signal
            printk(KERN_INFO "my_kthread received signal\n");
            // Clear the signal
            flush_signals(current);
            // Add your signal handling logic here
        }
    }
    return 0;
}

static int __init my_module_init(void)
{
    // Create and start the kernel thread
    my_kthread = kthread_run(signal_handler, NULL, "my_signal_thread");
    if (IS_ERR(my_kthread)) {
        printk(KERN_ERR "Failed to create kthread\n");
        return PTR_ERR(my_kthread);
    }
    printk(KERN_INFO "my_module loaded\n");
    return 0;
}

static void __exit my_module_exit(void)
{
    if (my_kthread) {
        kthread_stop(my_kthread);
    }
    printk(KERN_INFO "my_module unloaded\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
```

While analyzing the binary in Ghidra, look for similar patterns where signal status is checked (`signal_pending`) and specific actions are taken based on the signal received. The key is to find the specific comparison (`cmp` or equivalent `if` in decompiled code) that branches to the privilege escalation routine only when a particular, likely non-standard, signal value is matched. Use the Symbol Tree to find known functions or entry points and navigate through the code, utilizing the Decompiler view to understand the control flow and logic leading to the `give_root()` function call.
