LWN.net Logo

System calls and rootkits

By Jake Edge
September 10, 2008

A patch to add some security checks before making system calls would seem like a reasonable addition to the kernel, but because it is, at best, a half-measure, it received a less than enthusiastic response. Preventing rootkits—malware that alters the kernel to hide its presence and function—from altering the system call table was the rationale behind the patch, but it would only work for the current crop of rootkits. Once that change was made, rootkit authors would just change their modus operandi in response.

There are many possible ways that a root user—or malware running as root—can modify a Linux system to run rootkit code. Some currently "popular" rootkits modify the system call table, though it is ostensibly read-only. Some commercial malware scanners that run on Linux have also been known to use this technique. In both cases, certain system calls are re-routed from the standard kernel code to code that lives elsewhere. That code, running in kernel mode, can then do just about anything it wants with the system.

Arjan van de Ven proposed a patch that hooked into the system call entry code to check the address of the call to ensure that it was within the addresses occupied by kernel code. He describes the change and its impact this way:

The patch below, while obviously not perfect protection against malware, adds some cheap sanity checks to the syscall path to verify the system call is actually still in the kernel code region and not some external-to-this region such as a rootkit.

The overhead is very minimal; measured at 2 cycles or less. (this is because the branches get predicted right and the rest of the code is almost perfectly parallelizable... and an indirect function call is a branch issue anyway)

Various kernel hackers pointed out the flaws inherent in that scheme. As Andi Kleen succinctly puts it:

This just means that the root kits will switch to patch the first instruction of the entry points instead. [...] So the protection will be zero to minimal, but the overhead will be there forever.

One of the more interesting ideas to come out of the discussion was Alan Cox's thoughts on using a hypervisor to enforce protections:

The only place you can expect to make a difference here is in virtualised environments by teaching KVM how to provide 'irrevocably read only' pages to guests where the guest OS isn't permitted to change the rights back or the virtual mapping of that page.

Ingo Molnar described a rather complicated scheme that might increase the likelihood of a rootkit being detected, but with a fairly high cost—in build complexity as well as the ability to debug the resulting kernel. The compiler would be changed to insert calls to rootkit checks randomly throughout the kernel binary in ways that would be difficult or impossible for a rootkit to detect and evade. In the end, though, a rootkit could simply install a new kernel that does exactly what it wants, then cause, or wait for, a reboot.

Without some kind of hardware enforcement (e.g. Trusted Platform Module) or locked-down virtualization, Linux is defenseless against attacks that run as root. The kernel could change to thwart a particular kind of attack, such as van de Ven's patch, but other kinds of attacks will still succeed. It is clearly a situation where "the only way to win is not to play this game", as Pavel Machek—amongst others—noted in the thread.

In the end, van de Ven wrote off the patch as an exercise in measuring the cost of this kind of runtime checking. It was fairly low cost solution, but without any major upside. The real upside was getting kernel hackers thinking about the problem, which could lead to some better solutions down the road.


(Log in to post comments)

System calls and rootkits

Posted Sep 12, 2008 15:21 UTC (Fri) by cde (guest, #46554) [Link]

If Linux had been based on a micro-kernel design, getting a rootkit install would have proven more difficult (although not impossible), since the area to secure is much smaller. But at the beginning of the 90's few were thinking years ahead of the security issues that would arise...

System calls and rootkits

Posted Sep 12, 2008 20:27 UTC (Fri) by giraffedata (subscriber, #1954) [Link]

If Linux had been based on a micro-kernel design, getting a rootkit install would have proven more difficult (although not impossible), since the area to secure is much smaller.

I guess you mean getting a rootkit to install into the kernel would be more difficult. But as there would be correspondingly more places than the kernel into which to install a rootkit, I don't think the overall ease of installing a rootkit would be any different.

Note that even with Linux as it exists, a decent rootkit need not touch the kernel.

Microkernels

Posted Sep 14, 2008 22:59 UTC (Sun) by mlankhorst (subscriber, #52260) [Link]

Hurd is based on a microkernel.. yet still no stable release in sight..
linux was more pragmatical and based it on minix

Microkernels

Posted Sep 15, 2008 0:47 UTC (Mon) by vonbrand (subscriber, #4458) [Link]

No, Linux is not based on Minix (which is a microkernel, by the way). Linux was written according to published Unix design.

This common misconception is due to Linus running Minix for 386 while developing Linux. Fortunately, when Linus fat-fingered and killed his Minix, Linux was already far enough along to fight it on its own.

System calls and rootkits

Posted Sep 13, 2008 8:05 UTC (Sat) by geertj (subscriber, #4116) [Link]

> Without some kind of hardware enforcement (e.g. Trusted Platform Module) or locked-down virtualization, Linux is defenseless against attacks that run as root

SELinux is another technique that can protect against attacks that run as root.

System calls and rootkits

Posted Sep 14, 2008 16:35 UTC (Sun) by spender (subscriber, #23067) [Link]

Yea, it worked great against that exploit I wrote that disabled SELinux.

Sorry, but once you compromise the kernel, SELinux is useless.

-Brad

System calls and rootkits

Posted Sep 22, 2008 11:40 UTC (Mon) by robbe (guest, #16131) [Link]

> that exploit I wrote that disabled SELinux.

URL?

> Sorry, but once you compromise the kernel, SELinux is useless.

Nobody will argue that. Not that your parent post talks about "running as
root", not "in the kernel".

System calls and rootkits

Posted Sep 22, 2008 20:49 UTC (Mon) by nix (subscriber, #2304) [Link]

If you're root there are a simply enormous number of ways to compromise
the kernel or DoS the box to its knees. Maybe SELinux will eventually be
able to plug them all but it's not there yet.

(I saw one product for Solaris many years ago whose salesman claimed that
it protected the box from denials of service under 'all conditions',
specifically including conditions requiring physical access. I disproved
this bizarreclaim in the obvious way: pulling the plug.)

System calls and rootkits

Posted Jul 22, 2010 0:25 UTC (Thu) by petermag (guest, #7550) [Link]

If u have implement any rootkits, u will know that the best way to do it IS NOT hook at the syscall level (eg, because "sys_read" can be used for so many purposes). Instead, it is much better to do it at the lower level (eg, VFS layer). But if u can hook the syscall table, and so can u unpatch the patch that Arjan has put in to protect the syscall table. And likewise, many other techniques like making the ".text" region read-executable only, is really a joke - because u can easily undo it if u are a rootkit. Eg, ftrace have to make the region writeable momentarily and then switching it back to readonly - exactly the same sequence of steps can be executed by the rootkit kernel module as well. In general "rootkit" means that the system is alreayd 0wned (or compromised). Comments?

Copyright © 2008, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds