Re: Kernel-loadable Root Kits

From: D J Hawkey Jr (
Date: 09/08/01

Date: Sat, 8 Sep 2001 10:22:11 -0500
From: D J Hawkey Jr <>
To: Krzysztof Zaraska <>

On Sep 08, at 04:24 PM, Krzysztof Zaraska wrote:
> On Sat, 8 Sep 2001, D J Hawkey Jr wrote:
> > > System is violated,
> > > Root kit is installed,
> > > Root kit [binaries] are deleted from the machine.
> > >
> > > Solution:
> > >
> > > Reboot machine
> >
> > Rebooting won't necessarily fix anything. IIRC, one Linux rootkit
> > replaces a module with the backdoor. If the kernel needed that module
> > once, it'll need it again.
> It will fix if the trojan module is removed. See below.

Well, "replaced" might be better phrasing, no? If the kernel needed it
(as opposed to an user loading it), chances are it'll want it again.

> > > How does one DETECT that the root kit is there in the first place to know to
> > > reboot it?
> >
> > Tripwire.
> Not straightforward. Scenario described above suggested doing something
> like
> # kldload trojan.ko && rm /modules/trojan.ko
> So the only alert you may get from tripwire is that ctime of /modules is
> changed.

That'd raise my short-hairs; that tree ought to be [completely?] static.

> However, I was able to do that:
> lhotse# kldstat
> Id Refs Address Size Name
> 1 2 0xc0100000 21e4f4 kernel
> 2 1 0xc0784000 12000 linux.ko
> lhotse# cp /modules/warp_saver.ko /tmp
> lhotse# kldload /tmp/warp_saver.ko
> lhotse# kldstat
> Id Refs Address Size Name
> 1 3 0xc0100000 21e4f4 kernel
> 2 1 0xc0784000 12000 linux.ko
> 3 1 0xc0832000 2000 warp_saver.ko
> So it's possible to load a kernel module not located under
> /modules. So if attacker does
> # kldload /tmp/trojan.ko && rm /tmp/trojan.ko
> tripwire won't find anything.

Except for a ctime change on /tmp (or wherever), you're right.

> I thing the original question was: how to find a trojaned module in
> memory if there's no relevant binary on disk?
> However, in case of deleting module binary a reboot removes the root kit
> and assuming that no other changes to system were made effectively locks
> attacker out. Also, someone doing kldstat could see the trojan (if it's
> not stealth). So this attack scenario is useful only if:
> (i) machine has long uptime (no power failures etc.)
> (ii) no one does kldstat (assuming module is not stealth)
> Condition (ii) may be simply eliminated by adding kldstat to /etc/security.

Again, true enough.

I've added quite a bit of stuff to /etc/security.

> We may also consider adding a feature to kldload to load only modules
> from under /modules but I'm afraid this may be circumvented by attacker
> fetching her own kldload. A better way would be to implement an
> appropriate lock in kernel code but I don't know if it's possible.

The first pro'lly isn't worth the effort.

You lost me with the last bit; a lock to determine or do what, prevent
userland 'kldload's? This would seem to be a Good Thing(tm), but how do
you lock the lock - or would this be a kernel build-time option? If I'm
with you, it seems to me you'd also have to see that the kernel loads
all the modules at boot that it would need to fulfill all runtime
requirements, too, else it may load a trojan in the course of uptime.
Either that, or build 'em into the kernel.

> As for the question of locating the trojan code in memory my (unverified
> and possibly not implementable since I'm not a kernel hacker) idea is:
> read the module code by /proc or otherwise, fill all data area with 0's
> and compare MD5 checksums.

Compare against what, and when? I don't follow you here, either.

> Tripwire for running binaries ;)
> All comments welcome.

If 'kldload' logs [via syslogd], most of this activity would be traceable.
Now, most crackers will sanitize the log(s), but that might leave tell-tail
holes in time, too. One could log remotely, to [help] keep log integrity.

All in all, it seems to me a kernel that needs no KLD modules, and denies
all KLD loading, would be the easiest and most effective solution.

> Regards,
> Kris


Windows: "Where do you want to go today?"
Linux: "Where do you want to go tomorrow?"
FreeBSD: "Are you guys coming, or what?"
To Unsubscribe: send mail to
with "unsubscribe freebsd-security" in the body of the message

Relevant Pages

  • [patch 00/10] PI-futex: -V1
    ... We are pleased to announce "lightweight userspace priority inheritance" ... No registration, no extra kernel ... only a single owner may own a lock (i.e. no ... Priority Inheritance - why, oh why??? ...
  • Re: CFR: New NFS Lock Manager
    ... It also includes minor fixes to support 64bit architectures and RELENG_7. ... Lock Manager which runs in kernel mode and uses the normal local locking infrastructure for its state. ... A single thread should be sufficient for the NLM since it should rarely block in normal operation. ...
  • [patch 3/6] lightweight robust futexes: docs
    ... +The robust futex ABI ... for kernel assist of cleanup of held locks on task exit. ... will attempt to process both lists on each task ... pointer to a single linked list of 'lock entries', one per lock, ...
  • Re: FreeBSD 7.0 crashed when running super-smack upon PostgreSQL
    ... Is there any chance I can get remote access to a box holding the synchronized kernel, kernel debugging symbols, source code, and core dump? ... It sounds like TCP in a user thread is stumbling over a violation of system invariants (don't sleep while holding a mutex) performed by another thread. ... We need to track down the original thread and figure out why it's sleeping while holding that lock -- perhaps it's a user thread performing a copyin/copyout holding the lock, or perhaps an ithread or other software interrupt thread acquiring a lock of an inappropriate type while holding the lock. ... kgdb has its own thread ID scheme so you'll need to use info threads to track down the right kgdb thread id before you can select the identified kernel thread/process. ...
  • Re: [PATCH] [13/16] HWPOISON: The high level memory error handler in the VM v3
    ... And anon_vma lock nests inside i_mmap_lock. ... right now to consume. ... will make the kernel bug. ... for pagecache pages), this may not be able to trigger the race I was ...