Wednesday, May 15, 2013

Linux PERF_EVENTS root exploit - CVE-2013-2094 (quick way to fix it)

Recently a quite critical flaw has been found in the PERF_EVENT code in Linux.

The problem is a failure at checking a 64-bits variable (cast to a 32-bits int) passed by user space, resulting to out-of-bounds access of an array in kernel space.

Here is the exploit: http://packetstormsecurity.com/files/121616/semtex.c

The bug has been already fixed mainstream: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8176cced706b5e5d15887584150764894e94e02f

But lots of distro kernels are affected by this bug, so they're vulnerable to the root exploit (like all the RH / CentOS 2.6.32-based kernels).

A temporary solution, waiting for a new kernel to come out, can be to create a kernel module to "inject" the fix into the kernel at runtime, using the kprobe framework.

Here is the source code of the module:
https://www.develer.com/~arighi/linux/fix/CVE-2013-2094/perf-bug-fix.tar.gz

This module injects the fix by wrapping the buggy function perf_swevent_init() using the kprobe framework.

This would allow to provide a fix really soon, and it works with any kernel affected by this bug.

To compile it (on CentOS - instructions are almost identical in other distro):

  $ sudo yum install kernel-devel
  $ tar xvzf perf-bug-fix.tar.gz
  $ cd perf-bug-fix
  $ make

How to load the module and apply the fix:

 $ sudo insmod wrapper.ko

That's it. Now let's test the exploit.

Without wrapper.ko loaded:

cpuser1@testdomain1.com [/dev/shm]# id -u
521
cpuser1@testdomain1.com [/dev/shm]# ./a.out
...
 -sh-4.1# id -u
0

With wrapper.ko:

cpuser1@testdomain1.com [/dev/shm]# ./a.out
a.out: test.c:51: sheep: Assertion `!close(fd)' failed.
Aborted (core dumped)
cpuser1@testdomain1.com [/dev/shm]# id -u
521