If you think there are hidden modules laying in your kernel,
you can probe the linked list which hosts their structs.

Let's consider an evil module which has patched both the
sys_query_module to block lsmod(1) and the sys_read to
prevent root from finding it by looking at /proc/modules

Eg:

SLaCKy:~/KSTAT# lsmod
Module                  Size  Used by
ppp_deflate            40536   0  (unused)
serial_cs               5040   0  (unused)
pcnet_cs               10052   1
8390                    5860   0  [pcnet_cs]
ds                      6088   2  [serial_cs pcnet_cs]
i82365                 21276   2
pcmcia_core            43424   0  [serial_cs pcnet_cs ds i82365]
bsd_comp                3620   0

SLaCKy:~/KSTAT# cat /proc/modules
serial_cs               5040   0 (unused)
pcnet_cs               10052   1
8390                    5860   0 [pcnet_cs]
ds                      6088   2 [serial_cs pcnet_cs]
i82365                 21276   2
pcmcia_core            43424   0 [serial_cs pcnet_cs ds i82365]
bsd_comp                3620   0 (unused)

SLaCKy:~/KSTAT# ./kstat -M

knull at address 0xc283a000
oMBRa at address 0xc2838000   <------- not showing under lsmod output,
serial_cs at address 0xc2835000		nor under /proc/modules
pcnet_cs at address 0xc282f000
8390 at address 0xc282c000
ds at address 0xc2827000
i82365 at address 0xc281c000
pcmcia_core at address 0xc2810000
bsd_comp at address 0xc280e000

What's that knull ? It simply is a LKM that does NOTHING. It is
loaded by kstat to get the initial address of the linked list and
is then removed, so don't worry. You can find the source in the
relevant directory.

Now we can probe it:

SLaCKy:~/KSTAT# ./kstat -m 0xc2838000

LKM found at 0xc2838000 !

Name:   oMBRa
Size:   4096
Flags:  MOD_RUNNING
First Registered Symbol:        open at 0xc2838f88

But there are other ways to obfuscate modules in the kernel.
Like, say, zero out the struct module members *name, size and
*refs. In this case it will easily be visible, as all modules
will disappear from lsmod(1) output with an error like this:

SLaCKy:~/KSTAT# lsmod
Module                  Size  Used by
lsmod: QM_INFO: Invalid argument

Moreover, we will not be able to load any further module like
knull. At this point, we can try to locate the first legal
module, and then probe higher memory address to find a module
structure with a null name and a size of 0.

To accomplish this, there are two ways. We MUST know the address
range in which our modules are located, or go finding the first
legal module's address by searching for its name, and then for
a pointer to that memory location in /dev/kmem.

As you can see from the output of ksyms(1) with the -m flag, all
modules are contained in a fixed range, usually jumping from 
address to address between 0x1000 and 0x3000. So, by knowing (and
we always should know which modules are loaded at init, why and
where) the first address, we can have a few tries with kstat(1) with
the -m flag.

As for now, I decided not to implement the second way, as is more
error prone, and as I think admins should know what they're doing.
Let's attackers have tedious times searching kmem to patch it.


BTW, we can try to pinpoint the right address out by looking at
bogus system calls, which reside in the space of the rogue LKM.
