LWN.net Logo

The details on loading rootkits via /dev/mem

The details on loading rootkits via /dev/mem

Posted Apr 23, 2009 0:00 UTC (Thu) by spender (subscriber, #23067)
In reply to: The details on loading rootkits via /dev/mem by const-g
Parent article: The details on loading rootkits via /dev/mem

"Thus it will surely segfault." -- Are you 100% sure about that?
Let's ignore for starters that the process doesn't segfault, the kernel OOPSes and the process is terminated with SIGKILL.
In fact, in reference to your assumption that the syscall table is read-only on x86, you're being fooled by the fact that it exists in the ".rodata" section of the kernel. The .rodata section isn't read-only at all, unless CONFIG_DEBUG_RODATA is enabled. Maybe it's the case that on your distro, that option happens to be enabled in the kernel. I just took a look at the kernel config for the latest Debian kernel. CONFIG_DEBUG_RODATA is disabled. It seems to be enabled however on RHEL/CentOS kernels. I haven't bothered to examine others.

Mr. Lineberry mentions that his technique doesn't work against RHEL, which is why he had to compile a custom kernel to demonstrate it. Note that I'm not praising Mr. Lineberry or his technique at all -- in fact his work is essentially plagiarized and provides nothing new (remove subtracting 0xc0000000 from virtual addresses and you have the exact same rootkit published in Phrack in 2001).

But you weren't purely talking about Mr. Lineberry's technique, as you made the blanket statement:
"To use /dev/mem or /dev/kmem, one has to find a way to change writable memory (which will be data and not executable code) in such a way that it will cause kernel to run a desirable code with predictable results. While the kernel lacks data constraints checks in most places (usually assuming that safe and verified code runs), it is not an easy task. At least not as easy as the authors make it sound."

This is just completely false and nonsensical. If for a given virtual address in kernelspace, it happens to be marked as read-only (so CONFIG_DEBUG_RODATA is enabled), it does not at all follow that it's impossible to write to the memory or that the attacker is stuck with only writing to "data and not executable code" so as to "cause [the] kernel to run a desirable code with predictable results". There are a number of different approaches, but the most obvious is to simply modify the page table entry associated with the virtual address the attacker is attempting to modify. To do this, a review of the code of set_pte_vaddr and the exported swapper_pg_dir symbol would be of use. If you actually knew as much as you think you know, I wouldn't have to generate these scenarios for you.

As for mmap checking and your definition of a "long time" I would simply refer you to my first post in this thread, which you must have glossed over.

In summary: do what I suggested initially and read the Intel manuals. Really. Or keep writing posts on the subject: I know of at least one rootkit author who's getting a kick out of them.

-Brad


(Log in to post comments)

The details on loading rootkits via /dev/mem

Posted Apr 23, 2009 8:15 UTC (Thu) by const-g (subscriber, #5006) [Link]

You wrote:

"There are a number of different approaches, but the most obvious is to simply modify the page table entry associated with the virtual address the attacker is attempting to modify. To do this, a review of the code of set_pte_vaddr and the exported swapper_pg_dir symbol would be of use. If you actually knew as much as you think you know, I wouldn't have to generate these scenarios for you."

This is what I meant when I wrote in my first post:

"Of course if module interface is available, one can load a malicious code that can set arbitrary memory as both writable and executable. There are even (usually un-exported but obtainable via System.map or /proc/kallsyms) kernel functions that will do it for you. Using module interface is much more practical to achieve the result described in the article."

Or are you claiming that you know of a "trick" to change page tables permissions by using io on /dev/mem (without mmap)?

I do not think /dev/mem has much longer to live. The drivers (Xorg) are encouraged to use /sys/.../resource files to map what they need and the need for /dev/mem will be eventually gone.

[root@constg ~]# pidof Xorg
2702
[root@constg ~]# cat /proc/2702/maps | grep /sys
a7fc4000-b7fc4000 rw-s e0000000 00:00 6798 /sys/devices/pci0000:00/0000:00:02.0/resource2
b7fc4000-b8044000 rw-s f8080000 00:00 6797 /sys/devices/pci0000:00/0000:00:02.0/resource0
b8044000-b80c4000 rw-s f8000000 00:00 6797 /sys/devices/pci0000:00/0000:00:02.0/resource0

The details on loading rootkits via /dev/mem

Posted Apr 23, 2009 12:52 UTC (Thu) by spender (subscriber, #23067) [Link]

You keep revising what you "meant" to say (forgetting the self-sufficient sentences that are just factually wrong, which no ex post facto revising can fix), and again your revisions are completely wrong.

You say "Of course if module interface is available, one can load a malicious code that can set arbitrary memory as both writable and executable."

Wrong again; module support isn't necessary to set arbitrary memory as both writable and executable. And yes, it can be done purely with read() and write() on /dev/mem as I've already said. You can call it a "trick" if you like, but if you did the reading I suggested it would be simply "textbook behavior."

Since you're clearly unwilling to educate yourself, there's no point really in wasting any more time with this.

-Brad

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